如何在MVC中使用带有查询参数的Ninject?

时间:2011-02-04 23:11:15

标签: asp.net-mvc ninject

我正在关注Steven Sanderson的Pro MVC2书,并对使用Ninject提出疑问。

在体育商店示例中,我们有Global.asax.cs

 ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

NinjectControllerFactory定义为:

public class NinjectControllerFactory : DefaultControllerFactory

{
    //A Ninject "kernet" is the thing that can supply object instances
    private IKernel kernel = new StandardKernel(new SportsStoreServices());


    protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
    {
        return (IController)kernel.Get(controllerType); 
    }

    private class SportsStoreServices : NinjectModule
    {
        public string QString = null;
        public override void Load()
        {

            Bind<IProductsRepository>().To<SqlProductsRepository>()
                .WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString);


        }
    }

}

如您所见SqlProductsRepository正在从配置文件中获取连接字符串。如果我需要根据URL查询字符串参数在此做出决定,例如如果param1 = true我想从一个存储库加载另一个存储库,我该怎么做?我试图了解如何在Load()方法中访问查询参数,但我无法找到预先填充的位置。

同样Load()是根据查询参数做出决定的正确位置,还是我应该以某种方式在Controller中做出这个决定?

2 个答案:

答案 0 :(得分:1)

一个人将拥有多个具有.WithMetadata(或其特殊情况,.Named())的绑定。然后,在解析时,您需要将元数据过滤器和/或名称参数传递到.Get<>()调用以指示绑定。一个小但在这里搜索将产生示例,但到目前为止,ninject示例的最佳来源是ninject测试,它们非常干净并且是ninject文档没有得到他们应得的爱(即v2更新)的原因之一。

即,您将名称或元数据过滤器作为额外的参数放入:

    return (IController)kernel.Get(controllerType, **here**); 

至于如何在更复杂的情况下管理这个问题的最佳实践,我个人会阅读Brand Wilson关于他们如何在MVC 3中做到这一点的帖子。

我想这取决于你的目的地和目标:

  1. 在你学习的过程中做一些样本 - 抨击上面的
  2. 整理基于DI的体系结构,让您开心,运行和购买Dependency Injection in .NET by Mark Seemann,强烈考虑ASP.NET MVC 3并以任何方式阅读Brad Wilson文章系列

答案 1 :(得分:0)

模块的Load()方法仅在应用程序启动并且内核初始化时被调用。因此,没有请求上下文来做出决定。

如果是我,我会将两个存储库注入控制器并让控制器决定使用哪个存储库。这样你就可以编写单元测试来验证它是否做出了正确的决定。