Внедрить MembershipProvider в ASP.NET MVC AccountController

Шаблоны проектов ASP.NET MVC 1.0 включают класс AccountController, который поддерживает внедрение конструктора:

public AccountController(IFormsAuthentication formsAuth, 
    IMembershipService service)
{
    FormsAuth = formsAuth ?? new FormsAuthenticationService();
    MembershipService = service ?? new AccountMembershipService();
}

Также включен класс AccountMembershipService, который также поддерживает внедрение конструктора:

public AccountMembershipService(MembershipProvider provider)
{
    _provider = provider ?? Membership.Provider;
}

Я уверен, что многие из вас использовали их для модульного тестирования, но моя цель - внедрить SqlMembershipProvider с помощью Windsor и, таким образом, настроить его во время выполнения с использованием файлов Windsor XML, а не web.config. Другими словами, я хочу использовать внедрение конструктора для класса AccountMembershipService, и я хочу продолжать использовать встроенную систему членства ASP.NET 2.0. Я просто хочу, чтобы конфигурация системы членства проходила через Windsor IoC.

Возможно ли это без написания моего собственного MembershipProvider, или SqlMembershipProvider плохо работает с IoC?

Из MSDN: " Конструктор SqlMembershipProvider вызывается ASP.NET для создания экземпляра класса SqlMembershipProvider, как указано в конфигурации приложения. Этот конструктор не предназначен для использования из вашего кода. "

Я считаю, что Фил задал очень похожий вопрос., вот ответы он получил.

Thanks for your help.


UPDATE: Just to be clear, my reason for suppling the application's MembershipProvider via DI is to support multiple tenants. Each tenant has an isolated database with ASP membership tables. DI allows me to switch connection strings at runtime and thus keep the core application agnostic about which database is being used for each tenant. Windsor is controlling the DI and it "knows" which tenant makes the request via url:
var url = HttpContext.Current.Request.ServerVariables["HTTP_HOST"]

Майк Хэдлоу пишет об этой технике . Я просто пытаюсь интегрировать SqlMembershipProvider в его использование этого дизайна IoC.


person Robert Claypool    schedule 28.05.2009    source источник
comment
Одна деталь, которая может раскрыть эту проблему: что такое Membership.Provider в конструкторе AccountMembershipService?   -  person Harper Shelby    schedule 29.05.2009
comment
.Provider - это поставщик членства по умолчанию для приложения, предоставляемого с помощью абстрактного базового класса System.Web.Security.MembershipProvider.   -  person Robert Claypool    schedule 29.05.2009
comment
Если конструктор AccountMembershipService получает нулевой поставщик, Membership.Provider вернет SqlMembershipProvider (созданный средой выполнения) на основе настроек web.config. Это поведение, которое я хочу заменить через Виндзор.   -  person Robert Claypool    schedule 29.05.2009
comment
Какова твоя настоящая цель? Внедрение MembershipProvider не имеет ничего общего с его настройкой Виндзором.   -  person Mauricio Scheffer    schedule 29.05.2009
comment
@mausch Приложению требуется несколько клиентов, каждый с изолированной базой данных и таблицами членства. Я использую Windsor для отключения компонентов в зависимости от контекста (URL). SqlMembershipProvider - это тот, который я хочу отключить: tenant1.example.com и tenant2.example.com будут иметь разные css, connectionString, provider и т. Д., Указанные в конфигурации Windsor. Майк Хэдлоу объясняет метод mikehadlow.blogspot.com / 2008/11 /, но у меня возникли проблемы с переключением SqlMembershipProvider, поскольку этот конструктор не предназначен для использования из вашего кода.   -  person Robert Claypool    schedule 29.05.2009
comment
аааа ладно, теперь я понял ... однако у вас может быть несколько поставщиков членства ... Я обновлю свой ответ.   -  person Mauricio Scheffer    schedule 29.05.2009
comment
Обновите свой вопрос и добавьте эту новую информацию.   -  person Mauricio Scheffer    schedule 29.05.2009


Ответы (1)


Предполагая, что ваши поставщики членства настроили что-то вроде этого:

<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>

вы можете заставить 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)
person Mauricio Scheffer    schedule 29.05.2009
comment
Работал как шарм! Спасибо, mausch. - person Robert Claypool; 01.06.2009