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

时间:2012-03-20 11:13:00

标签: asp.net-mvc-3 ninject

我已经开始在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。

我的问题:

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

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

2 个答案:

答案 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