2012-03-20 56 views
7

我已經開始在ASP.NET MVC 3項目中使用Ninject,使用nuget包附帶的標準引導過濾器,如下所示。Ninject-在N層MVC3應用程序的域模型層中設置綁定的正確方法是什麼?

/// <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,設置綁定等。這似乎是對我來說太離譜了。

但是,我認爲在Domain Model層中,CookieManager應該以DI方式傳入SecureObjectSerializer。

我的問題:

  1. 有綁定註冊在域模型層,我應該創建域模型層內的Ninject引導程序?如果是這樣,我應該如何觸發這一點。我會提供一個鉤子,並在MVC項目中調用類似DomainModel.BindModelDependencies(kernel);的東西。

  2. 當需要解析對象的新實例時,這段代碼是什麼樣的?使用MVC引導程序時有點隱藏?

回答

6

您應該將NinjectModule放入域程序集(而不是Web程序集)中,您可以告訴ninject掃描您的域程序集並查找模塊。模塊只是一個繼承自NinjectModule基類並實現Load()的類。這樣Web項目只需要對域項目的引用。掃描應該是這個樣子:這兩個

之一:(實際上有一些更多的選擇,但這些都是我用的是主要的)

var assemblysToScan = "Assembly.*"; 
var assemblysToScan = new[] { "Assembly.Domain", "Assembly.Web" }; 

,然後就

kernel.Scan(x => 
       { 
        x.From(assemblysToScan) 
        x.AutoLoadModules(); 
       }); 

當你想解析一個對象時,只需把它作爲ctor參數,如果ninject正在管理你的對象,它會自動注入類型(基於你配置的綁定)。

編輯:

引用添加ninjectcommonservicelocator在您的引導程序(記不起確切的名字)& 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>(); 
    } 
} 

微軟的原因。實踐定位器是你的代碼不應該知道ninject是在蓋子下工作。相反,如果您更改容器,則使用可以重用的通用servicelocator。

個人我會避免這一點,只是注入一切。但如果你不能,你不能。

+0

謝謝。 「只是把它作爲一個論點」 - 在哪裏?在MVC中,這很好,但是當我想在MVC項目之外創建一個對象的實例時呢?你能提供一個更詳細的代碼示例嗎? – gb2d 2012-03-20 11:57:36

+0

你是指在你的域名代碼或網頁代碼? – AaronHS 2012-03-20 11:59:51

+0

,如果你的意思是你的域代碼,那麼正在執行的代碼在哪裏? – AaronHS 2012-03-20 12:01:51

3

接受的答案是指從Ninject.Extensions.ConventionsScan()方法。 Ninject 3.0用更強大的流暢接口替代了這個接口,可以進行動態程序集綁定。

kernel.Bind(x => x 
     .FromAssembliesMatching("*") 
     .SelectAllClasses() 
     .BindDefaultInterface()); 

冒險繼續在extension's Wiki

+0

供參考:您必須添加使用Ninject.Extensions.Conventions;獲取FromAssembliesMatching擴展方法。 – Aligned 2013-08-21 15:46:31

相關問題