将MembershipProvider注入ASP.Net MVC AccountController

Rob*_*ool 7 asp.net-mvc dependency-injection castle-windsor asp.net-membership sqlmembershipprovider

Asp.Net MVC 1.0项目模板包含一个AccountController类,它支持构造函数注入:

public AccountController(IFormsAuthentication formsAuth, 
    IMembershipService service)
{
    FormsAuth = formsAuth ?? new FormsAuthenticationService();
    MembershipService = service ?? new AccountMembershipService();
}
Run Code Online (Sandbox Code Playgroud)

一个AccountMembershipService类也包括在内,而且它也支持构造器注入:

public AccountMembershipService(MembershipProvider provider)
{
    _provider = provider ?? Membership.Provider;
}
Run Code Online (Sandbox Code Playgroud)

我相信你们中的许多人已经将这些用于单元测试,但我的目标是使用Windsor 注入一个SqlMembershipProvider,因此使用Windsor xml文件而不是web.config在运行时配置它.换句话说,我想实际使用AccountMembershipService类的构造函数注入,我想继续使用内置的ASP.Net 2.0 Membership系统.我只想让会员系统的配置通过Windsor IoC.

如果没有编写我自己的MembershipProvider,或者SqlMembershipProvider不能很好地与IoC一起使用,这是否可行?

来自MSDN:"ASP.NET调用SqlMembershipProvider构造函数来创建应用程序配置中指定的SqlMembershipProvider类的实例.此构造函数不应在您的代码中使用."

我相信菲尔提出了一个非常相似的问题,但我没有足够的经验来解决他收到的答案.

谢谢你的帮助.


更新: 为了清楚起见,我通过DI提供应用程序的MembershipProvider的原因是支持多个租户.每个租户都有一个带有ASP成员资格表的独立数据库.DI允许我在运行时切换连接字符串,从而使核心应用程序不知道每个租户使用哪个数据库.Windsor正在控制DI,它"知道"哪个租户通过url发出请求:
var url = HttpContext.Current.Request.ServerVariables["HTTP_HOST"]

Mike Hadlow 在这里讨论这种技术. 我只是想将SqlMembershipProvider集成到他对这个IoC设计的使用中.

再次感谢.

Mau*_*fer 3

假设您的会员提供商配置如下:

<membership>
    <providers>
        <clear/>
        <add name="www.tenant1.com" 
         type="System.Web.Security.SqlMembershipProvider, ..." 
         .../>
        <add name="www.tenant2.com" 
         type="System.Web.Security.SqlMembershipProvider, ..." 
         .../>
    </providers>
</membership>
Run Code Online (Sandbox Code Playgroud)

您可以让 Windsor 选择合适的提供商,如下所示:

var container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<MembershipProvider>()
    .LifeStyle.Transient
    .UsingFactoryMethod(() => Membership.Providers[HttpContext.Current.Request.Url.Host]));
... (your controller registrations, etc)
Run Code Online (Sandbox Code Playgroud)