我正在关注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中做出这个决定?
答案 0 :(得分:1)
一个人将拥有多个具有.WithMetadata(或其特殊情况,.Named()
)的绑定。然后,在解析时,您需要将元数据过滤器和/或名称参数传递到.Get<>()
调用以指示绑定。一个小但在这里搜索将产生示例,但到目前为止,ninject示例的最佳来源是ninject测试,它们非常干净并且是ninject文档没有得到他们应得的爱(即v2更新)的原因之一。
即,您将名称或元数据过滤器作为额外的参数放入:
return (IController)kernel.Get(controllerType, **here**);
至于如何在更复杂的情况下管理这个问题的最佳实践,我个人会阅读Brand Wilson关于他们如何在MVC 3中做到这一点的帖子。
我想这取决于你的目的地和目标:
答案 1 :(得分:0)
模块的Load()方法仅在应用程序启动并且内核初始化时被调用。因此,没有请求上下文来做出决定。
如果是我,我会将两个存储库注入控制器并让控制器决定使用哪个存储库。这样你就可以编写单元测试来验证它是否做出了正确的决定。