2010-08-17 17 views
1

我正在使用StructureMap構建一個asp.net MVC2 web應用程序。我創建了一個自定義的MembershipProvider。我得到它在啓動時正確初始化通過調用:在MembershipProvider.Initialize()中注入存儲庫?餿主意?

x.For<MembershipProvider>().Use(Membership.Provider); 
x.For<IMembershipProvider>().Use<CPOPMembershipProvider>(); 

在初始化(),我想實例化一個倉庫用於訪問用戶數據庫中的數據的。

於是,我把在私人財產在我定製的MembershipProvider:

private IUserRepository userRepository; 

而且,裏面初始化(),我稱之爲:

IUserRepository userRepository = ObjectFactory.GetInstance<IUserRepository>(); 

首先,是 「好的做法」,以在我的自定義MembershipProvider中實例化一個存儲庫?

其次,當我實現它時,好像我無法訪問在global.asax中正確設置的任何StructureMap配置。當我在上面的GetInstance()行之前調用Debug.WriteLine(ObjectFactory.WhatDoIHave())時,沒有任何配置數據存在(我確實從位於global.asax中的同一調試行中看到),並且我得到一個「調用GetInstance()時,沒有爲PluginFamily CPOP.Domain.Contracts.Repositories.IUserRepository定義的默認實例「錯誤。這是爲什麼?好像我在MembershipProvider中有一個完全不同的容器。

回答

3

在StructureMap中使用setter injection結束。可以通過調用來配置自定義MembershipProvider中的userRepository屬性:

CPOPMembershipProvider member = 
    (CPOPMembershipProvider) Membership.Providers["CPOPMembershipProvider"]; 
ObjectFactory.Configure(x => 
{ 
    ... 
    x.For<MembershipProvider>().Use(Membership.Provider); 
    x.For<IMembershipProvider>().TheDefault.Is.Object(member); 
    ... 
    x.For<IPatientRepository>().Use<PatientRepository>(); 
    x.For<IUserRepository>().Use<UserRepository>(); 
    x.SetAllProperties(y => { y.OfType<IUserRepository>(); }); 
    ... 
}); 

然後,調用目標實例上的BuildUp()。我在Application_Start()中執行此操作後,所有註冊表被調用並且StructureMap具有所有配置數據。

ObjectFactory.BuildUp(Membership.Providers["CPOPMembershipProvider"]); 

完成。

+0

正是我需要的。 – 2012-02-07 01:33:36

0

非常感謝您回答您的問題......這正是我一直在尋找的。

我略作修改,關鍵是配置通過了ObjectFactory(如上剛)一切使用的ObjectFactory對DependencyResolver容器:

UserMembershipProvider provider = 
(UserMembershipProvider)Membership.Providers["UserMembershipProvider"]; 

ObjectFactory.Configure(x => 
{ 
    x.For<ISessionFactory>() 
     .Singleton() 
     .Use(() => NHibernateInitializer.Initialize().BuildSessionFactory()); 
    x.For<IEntityDuplicateChecker>().Use<EntityDuplicateChecker>(); 
    x.For(typeof(IRepository<>)).Use(typeof(Repository<>)); 
    x.For(typeof(IRepositoryWithTypedId<,>)).Use(typeof(RepositoryWithTypedId<,>)); 
    x.SetAllProperties(y => 
    { 
     y.WithAnyTypeFromNamespaceContainingType<IEntityDuplicateChecker>(); 
    }); 
}); 

ObjectFactory.BuildUp(provider); 
DependencyResolver.SetResolver(
    new StructureMapDependencyResolver(ObjectFactory.Container)); 

這樣,一切從一個控制器工廠的角度來看作品,和的MembershipProvider在事實之後是「建立起來的」(因爲它已經在Application_Start之前構建,這要歸功於.NET)。上面的代碼是從Application_Start調用的。

0

成員資格提供者基本上是單身人士,這意味着只有單個實例將由ASP.NET創建。因此,除非在生產中當兩個線程同時使用相同的成員資格提供程序時需要某些意外,否則請勿將任何內容保留在私有字段/屬性中。

我只需要實現的ValidateUser,因爲我們不使用任何其他方法,我做了這樣的:

public bool ValidateUser(string userName, string password) 
{ 
    var session = DependencyResolver.Curret.GetService<ISession>(); 

    using (session) 
    { 
     using (var tx = session.BeginTransaction()) 
     { 
      // load the user from db and validate the password etc. 
      tx.Commit(); 
     } 
    } 
} 

當然,你需要配置DependencyResolver,StructureMap等,但問題是, ISession不保存在私人領域/財產。

相關問題