Asp.net mvc 2 正在MembershipProvider.Initialize()中注入存储库?坏主意?

Asp.net mvc 2 正在MembershipProvider.Initialize()中注入存储库?坏主意?,asp.net-mvc-2,structuremap,membership-provider,Asp.net Mvc 2,Structuremap,Membership Provider,我正在使用StructureMap构建一个asp.net MVC2 web应用程序。我已经创建了一个自定义成员资格提供程序。我通过调用以下命令在启动时对其进行正确初始化: x.For<MembershipProvider>().Use(Membership.Provider); x.For<IMembershipProvider>().Use<CPOPMembershipProvider>(); CPOPMembershipProvider member =

我正在使用StructureMap构建一个asp.net MVC2 web应用程序。我已经创建了一个自定义成员资格提供程序。我通过调用以下命令在启动时对其进行正确初始化:

x.For<MembershipProvider>().Use(Membership.Provider);
x.For<IMembershipProvider>().Use<CPOPMembershipProvider>();
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>(); });
    ...
}); 
在Initialize()中,我调用:

IUserRepository userRepository=ObjectFactory.GetInstance();
首先,在我的自定义MembershipProvider中实例化存储库是否是“良好做法”

其次,当我实现它时,似乎无法访问在global.asax中正确设置的任何StructureMap配置。当我在上面的GetInstance()行之前调用Debug.WriteLine(ObjectFactory.WhatDoIHave())时,没有任何配置数据(我确实从放置在global.asax中的同一调试行中看到),并且在调用GetInstance()时出现“没有为PluginFamily CPOP.Domain.Contracts.Repositories.IUserRepository定义默认实例”错误。为什么呢?似乎我在MembershipProvider中有一个完全不同的容器。

最终在StructureMap中使用。可以通过调用以下命令来配置自定义MembershipProvider中的userRepository属性:

x.For<MembershipProvider>().Use(Membership.Provider);
x.For<IMembershipProvider>().Use<CPOPMembershipProvider>();
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>(); });
    ...
}); 

完成。

非常感谢您回答您的问题……这正是我想要的

对我稍加修改,技巧是通过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));
UserMembershipProvider提供程序=
(UserMembershipProvider)成员资格。提供程序[“UserMembershipProvider”];
ObjectFactory.Configure(x=>
{
x、 For()
.Singleton()
.Use(()=>NHibernateInitializer.Initialize().BuildSessionFactory());
x、 For().Use();
x、 用于(typeof(IRepository))。使用(typeof(Repository));
x、 For(typeof(IRepositoryWithTypedId))。使用(typeof(RepositoryWithTypedId));
x、 SetAllProperties(y=>
{
y、 WithAnyTypeFromNamespaceContainingType();
});
});
ObjectFactory.building(提供者);
DependencyResolver.SetResolver(
新结构MapDependencyResolver(ObjectFactory.Container));

通过这种方式,一切都从控制器工厂的角度进行,并且成员资格提供程序是在事实之后“构建”的(因为它是在应用程序启动之前构建的,多亏了.NET)上面的代码是从应用程序开始调用的。

成员资格提供程序基本上是单实例的,这意味着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();
        }
    }
}
public bool ValidateUser(字符串用户名、字符串密码)
{
var session=DependencyResolver.Curret.GetService();
使用(会话)
{
使用(var tx=session.BeginTransaction())
{
//从数据库加载用户并验证密码等。
tx.Commit();
}
}
}
当然,您需要配置DependencyResolver、StructureMap等,但关键是ISession不保存在私有字段/属性中

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();
        }
    }
}