我已经开始在ASP.NET MVC 3项目中使用Ninject,使用nuget包附带的标准引导strapper,如下所示。
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
// Documentation for setting up Ninject in ASP.NET MVC3 app:
// https://github.com/ninject/ninject.web.mvc/wiki/Setting-up-an-MVC3-application
// Add bindings here. No modules required unless we need to add in further
// separation of concerns.
kernel.Bind<ISessionManager>().To<SessionManager>();
kernel.Bind<ICookieManager>().To<CookieManager>();
kernel.Bind<ILogManager>().To<LogManager>();
kernel.Bind<IStringOutput>().To<StringOutput>();
}
在我的域模型层中,有一个名为CookieManager
的类。在我的CookieManager
课程中,我正在使用名为SecureObjectSerializer
的课程。
我想使用依赖注入,以便CookieManager
不会与SecureObjectSerializer
绑定。
我不希望MVC项目必须知道SecureObjectSerializer,设置绑定等。这似乎让DI对我来说太过分了。
但我认为,在Domain Model层中,CookieManager应该以DI方式传入SecureObjectSerializer。
我的问题:
要在域模型层中注册绑定,我应该在域模型层中创建Ninject引导程序吗?如果是这样,我该如何触发。我是否会提供一个钩子并在MVC项目中调用类似DomainModel.BindModelDependencies(kernel);
的内容。
当解决对象的新实例时,这段代码会是什么样子?使用MVC引导程序时它有点隐藏吗?
答案 0 :(得分:6)
您应该将NinjectModule放在域程序集(而不是Web程序集)中,然后您可以告诉ninject扫描您的域程序集并查找该模块。 module只是一个继承自NinjectModule基类并实现Load()的类。这样,Web项目只需要对域项目的引用。扫描应该类似于:
这两个中的任何一个:(实际上还有一些选项,但这些是我使用的主要选项)
var assemblysToScan = "Assembly.*";
var assemblysToScan = new[] { "Assembly.Domain", "Assembly.Web" };
然后只是
kernel.Scan(x =>
{
x.From(assemblysToScan)
x.AutoLoadModules();
});
如果要解析对象,只需将其作为ctor参数,如果ninject正在管理对象,它将自动注入类型(基于您配置的绑定)。
编辑:
添加对ninjectcommonservicelocator的引用(无法记住确切名称)&amp; microsoft.practices.servicelocation
你的引导程序中的添加以下内容:
using Microsoft.Practices.ServiceLocation;
using CommonServiceLocator.NinjectAdapter;
var locator = new NinjectServiceLocator(kernel);
ServiceLocator.SetLocatorProvider(() => locator);
然后在你班上:
using Microsoft.Practices.ServiceLocation;
class CookieManager : ICookieManager
{
SecureObjectSerialiser secureObjectSerialiser;
CookieManager()
{
this.secureObjectSerialiser = ServiceLocator.Current.GetInstance<SecureObjectSerialiser>();
}
}
microsoft.practices定位器的原因是你的代码不应该知道ninject正在工作中。相反,如果更改容器,则使用可以重用的通用服务定位器。
个人我会避免这种情况,只是注入一切。但如果你不能,你就不能。答案 1 :(得分:3)
接受的答案是指Scan()
中的Ninject.Extensions.Conventions
方法。 Ninject 3.0用更强大的流畅界面取代了它,用于进行动态装配绑定。
kernel.Bind(x => x
.FromAssembliesMatching("*")
.SelectAllClasses()
.BindDefaultInterface());
冒险继续在extension's Wiki。