Подтвердить что ты не робот

Внедрить репозиторий для пользовательского поставщика членства с Ninject

Я пытаюсь внедрить репозиторий в пользовательский поставщик членства с ninject в MVC 3.

В MembershipProvider я пробовал следующее:

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

и

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

В моем модуле ninject я пробовал следующее:

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

Ни одно из вышеперечисленных работ.

Когда я использую (в global.asa)

kernel.Inject(Membership.Provider);

вместе с

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

он работает, но у меня нет управления жизненным циклом, и это приведет к ошибке "ISession is open" от NHibernate, потому что ISession - это InRequestScope, а репозиторий - нет.

4b9b3361

Ответ 1

Вы можете использовать подход @Очертания Remo Gloor в его сообщении в блоге об инъекции поставщика. Он включает в себя 3 этапа:

  • Добавьте [Inject] к любым свойствам вашего провайдера, которые вам нужно ввести (хотя образец, который он показывает), создает очень простой класс, единственная функция которого должна быть восприимчивой для инъекции свойств и пересылает любые запросы к реальному класс, реализованный с использованием инсталляции конструктора, - это стоит того)

    public class MyMembershipProvider : SqlMembershipProvider
    {
        [Inject]
        public SpecialUserProvider SpecialUserProvider { get;set;}
        ...
    
  • Создайте оболочку инициализатора, которая реализует IHttpModule, которая втягивает провайдера, вызывая его создание: -

    public class ProviderInitializationHttpModule : IHttpModule
    {
        public ProviderInitializationHttpModule(MembershipProvider membershipProvider)
        {
        }
    ...
    
  • Зарегистрируйте IHttpModule в своем RegisterServices: -

    kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();
    
  • нет 4; Ninject делает остальные - загружает все зарегистрированные IHttpModules, включая добавленные вами) во время последовательности запуска.

(Не забудьте прочитать комментарии о событиях в блоге и т.д.)


Наконец, если вы ищете что-то полностью braindead direct, которое решает его аккуратно, попробуйте этот ответ @Remo Gloor вместо


PS отличная запись на весь беспорядок Поставщик не является шаблоном @Mark Seemann. (и прелюбодейный плагин для его превосходной книги: Вложение зависимостей в .NET, в котором вам будет удобно находить этот материал из первых принципов)

Ответ 2

У меня была эта проблема

пользовательский поставщик членства, роли и профиля в другом проекте из MVC с использованием репозитория, когда я когда-либо вызываю провайдера, вложенный репозиторий был пустым.

попытался вызвать kernel.Inject(Membership.Provider); в NendjectWebCommon метод registerServices (ядро IKernel), но получил исключение

Результат всегда равен нулю, поскольку у asp.net есть собственное статическое свойство для членства. которое является member.provider. и этот экземпляр не является частью управления ninject экземпляра.

поэтому используйте для PostApplicationStartMethod

здесь является solouion от cipto добавить в NinjectWebCommon метод attrbute и method:

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

Ответ 3

Проблема в том, что вся инфраструктура членства является "родным" кодом .NET(System.Web.Security), который не знает о MVC и о контейнере DI, используемом MVC. Статический вызов для Membership.Provider возвращает поставщика членства на основе конфигурации, однако указанный тип провайдера создается с помощью простого вызова Activator.CreateInstance. Следовательно, инъекция зависимостей не имеет шанса нагнать и установить зависимость вашего репозитория от результата. Если вы явно настроили возвращаемый экземпляр с помощью Ninject, он может работать, потому что вы явно указали Ninject на объект, чтобы установить зависимости. Даже в этом случае он может работать только с введением свойств, а не с вводом конструктора, потому что экземпляр ранее был создан конфигурацией членства.

Подводя итог: вы не можете легко вводить зависимости в поставщик членства, потому что он не разрешен из контейнера инъекции зависимостей. Я думаю, у вас есть 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