Ninject - 在N-Tier MVC3应用程序的域模型层中设置绑定的正确方法是什么?

gb2*_*b2d 7 ninject asp.net-mvc-3

我已经开始在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>();
    } 
Run Code Online (Sandbox Code Playgroud)

在我的域模型层中,有一个名为的类CookieManager.在我的CookieManager课堂上,我正在使用一个名为的课程SecureObjectSerializer.

我想使用依赖注入,以便它CookieManager不会受到严重约束SecureObjectSerializer.

我不希望MVC项目必须知道SecureObjectSerializer,设置绑定等.这似乎对我来说DI太过分了.

但是,我认为在Domain Model层中,CookieManager应该以DI方式传入SecureObjectSerializer.

我的问题:

  1. 要在域模型层中注册绑定,我应该在域模型层中创建Ninject引导程序吗?如果是这样,我该如何触发.我会提供一个钩子并调用像DomainModel.BindModelDependencies(kernel);MVC项目中的东西.

  2. 在解决对象的新实例时,这段代码会是什么样的?使用MVC引导程序时它有点隐藏吗?

Aar*_*nHS 6

您应该将NinjectModule放在域程序集(而不是Web程序集)中,然后您可以告诉ninject扫描您的域程序集并查找该模块.module只是一个继承自NinjectModule基类并实现Load()的类.这样,Web项目只需要对域项目的引用.扫描应该类似于:

这两个中的任何一个:(实际上还有一些选项,但这些是我使用的主要选项)

var assemblysToScan = "Assembly.*";
var assemblysToScan = new[] { "Assembly.Domain", "Assembly.Web" };
Run Code Online (Sandbox Code Playgroud)

然后就是

kernel.Scan(x =>
                {
                    x.From(assemblysToScan)
                    x.AutoLoadModules();
                });
Run Code Online (Sandbox Code Playgroud)

如果要解析对象,只需将其作为ctor参数,如果ninject正在管理对象,它将自动注入类型(基于您已配置的绑定).

编辑:

添加对ninjectcommonservicelocator的引用(无法记住确切名称)µsoft.practices.servicelocation

在你的引导程序中添加以下内容:

using Microsoft.Practices.ServiceLocation;
using CommonServiceLocator.NinjectAdapter;

var locator = new NinjectServiceLocator(kernel);
ServiceLocator.SetLocatorProvider(() => locator);
Run Code Online (Sandbox Code Playgroud)

然后在你班上:

using Microsoft.Practices.ServiceLocation;

class CookieManager : ICookieManager
{
  SecureObjectSerialiser secureObjectSerialiser;

  CookieManager()
  {
    this.secureObjectSerialiser = ServiceLocator.Current.GetInstance<SecureObjectSerialiser>();
  }
}
Run Code Online (Sandbox Code Playgroud)

microsoft.practices定位器的原因是你的代码不应该知道ninject是在幕后工作.相反,如果更改容器,则使用可以重用的通用服务定位器.

我个人会避免这种情况,只是注入一切.但如果你不能,你就不能.