2011-04-08 51 views
18

我試圖注入倉庫與ninject自定義的成員提供在MVC 3進樣庫與Ninject

在我的MembershipProvider曾嘗試以下自定義成員資格提供:

[Inject] 
public ICustomerRepository _customerRepository{ get; set; } 

而且

[Inject] 
public TUMembershipProvider(ICustomerRepository customerRepository) 
{ 
    _customerRepository = customerRepository; 
} 

在我ninject模塊我嘗試了以下內容:

Bind<MembershipProvider>().ToConstant(Membership.Provider); 

以上都不是。

當我(在global.asa中)使用具有

[Inject] 
public ICustomerRepository _customerRepository{ get; set; } 

它的工作原理,但我沒有生命週期管理,這將導致一個「的Isession是打開」的錯誤

kernel.Inject(Membership.Provider); 

在一起從NHibernate,因爲ISession是InRequestScope和存儲庫不是。

+0

我一直停留在這件事上幾個月。 – 2011-05-31 19:36:36

回答

1

問題是,整個成員資格基礎架構是一個「本地」.NET代碼(System.Web.Security),它不知道MVC和MVC使用的DI容器。 對Membership.Provider的靜態調用會根據配置返回成員資格提供程序,但是,指定的提供程序類型將通過簡單的Activator.CreateInstance調用進行實例化。因此,依賴注入沒有機會啓動並設置存儲庫對結果的依賴。如果你使用Ninject顯式設置返回的實例,它可以工作,因爲你明確地給了Ninject這個對象來設置依賴關係。即使在這種情況下,它只能用於屬性注入而不用於構造函數注入,因爲實例是先前由成員資格配置創建的。

總結:您不能輕易地將依賴項注入成員資格提供程序,因爲它不是從依賴注入容器中解析的。 我覺得你有2種可能:

  1. 您可以直接創建自定義成員提供一個存儲庫,或者您通過按需一些其他手段(如Web上下文已經存在)來訪問它。
  2. 你走高一級,檢查將使用你的會員供應商的組件,並嘗試在那裏更改(使用從你的DI容器解決的成員供應商而不是未初始化的Memership.Provider)。如果這個「更高的組件」是窗體身份驗證,那麼這篇文章可能會有所幫助(使用依賴注入IFormsAuthentication和IMembershipService):http://weblogs.asp.net/shijuvarghese/archive/2009/03/12/applying-dependency-injection-in-asp-net-mvc-nerddinner-com-application.aspx
+0

我想知道爲什麼我無法在MVC庫本身中找到IMembershipService接口:您將獲得由Visual Studio模板生成的一個,如此處所述http://stackoverflow.com/questions/2349022/how-do-i-get- an-instance-of-asp-net-mvc-applications-membershipprovider-from – 2011-06-08 08:19:23

0

你嘗試你的資料庫「手動」解決,像這樣的回答: Ninject : Resolving an object by type _and_ registration name/identifier

+0

但是我仍然需要以某種方式獲取內核實例? – Luticka 2011-06-16 08:12:26

+0

如果您在實施IModule時註冊存儲庫(即MyModule:IModule),然後得到一個內核實例,你需要調用'IKernel kernel = new StandardKernel(new MyModule());' 參見http://ninject.codeplex.com/wikipage?title=Modules%20and%第二十條%20Kernel – 2011-06-19 10:06:36

5

您可以使用方法@Remo Gloor outlines in his blog post on provider injection。它包括3個步驟:

  1. 添加[Inject] s到你需要注入你的供應商的任何屬性(雖然他顯示模式 - 創建一個非常簡單的類,它的唯一功能是爲物業注入和轉發可收納一個真正的類的任何請求使用實現的構造器注入 - 是非常值得以下)

    public class MyMembershipProvider : SqlMembershipProvider 
    { 
        [Inject] 
        public SpecialUserProvider SpecialUserProvider { get;set;} 
        ... 
    
  2. 創建一個實現IHttpModule這在拉動提供商,引發其創作的初始包裝: -

    public class ProviderInitializationHttpModule : IHttpModule 
    { 
        public ProviderInitializationHttpModule(MembershipProvider membershipProvider) 
        { 
        } 
    ... 
    
  3. 註冊IHttpModuleRegisterServices: -

    kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>(); 
    
  4. 沒有4; Ninject完成剩下的工作 - 在啓動序列中引導所有註冊的IHttpModules,包括您添加的那個)。

(不要忘記閱讀重新壽命等對博客文章的評論)


最後,如果你正在尋找的東西完全新空房禁地直接說巧妙地解決了它,嘗試this @Remo Gloor answer instead


PS上全亂了很大的書面記錄是Provider is not a Pattern by @Mark Seemann。 (和他的優秀著作的oboligatory插頭: - Dependency injection in .NET,這將讓你從第一原理出舒適搞清楚這個東西)

2

我有這個問題

從MVC另一個項目自定義成員資格,角色和個人資料提供使用存儲庫時,當我調用提供者注入的存儲庫爲空。

試圖調用kernel.Inject(Membership.Provider);在NinjectWebCommon方法registerServices(IKernel內核)中,但得到了異常

結果始終爲空,因爲asp.net擁有它自己的membership.which是membership.provider的靜態屬性。並且此實例不是實例注入管理的一部分。

上PostApplicationStartMethod

所以這裏使用的是由cipto的soloution添加到NinjectWebCommon的attrbute和方法:

[assembly: WebActivator.PreApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "Start")] 
    [assembly: WebActivator.PostApplicationStartMethod(typeof(WebApp.App_Start.NinjectWebCommon), "RegisterMembership")] 
    [assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(WebApp.App_Start.NinjectWebCommon), "Stop")] 

    public static void RegisterMembership() 
    { 
     bootstrapper.Kernel.Inject(Membership.Provider); 
    }