Внедрить репозиторий для пользовательского поставщика членства с 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, а репозиторий - нет.
Ответы
Ответ 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
Ответ 4
Пробовал ли вы решают ваш репозиторий "вручную", как в этом ответе:
Ninject: разрешение объекта по типу _and_ registration name/identifier