Внедрить репозиторий в пользовательский провайдер членства с помощью Ninject - PullRequest
18 голосов
/ 08 апреля 2011

Я пытаюсь внедрить хранилище в пользовательский поставщик членства с помощью 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, а хранилище - нет.

Ответы [ 4 ]

5 голосов
/ 01 мая 2012

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

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

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

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

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

(не забудьте прочитать комментарии к сообщению в блоге о времени жизни и т. Д.).)


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


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

2 голосов
/ 20 апреля 2013

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

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

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

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

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

вот решение для cipto добавления к NinjectWebCommon атрибута и метода:

    [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);
    } 
1 голос
/ 06 июня 2011

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

Подводя итог: вы не можете легко внедрить зависимости в поставщик членства, потому что это не так.разрешается из контейнера для инъекций зависимости.Я думаю, что у вас есть 2 возможности:

  1. Вы создаете хранилище непосредственно в провайдере нестандартного членства или обращаетесь к нему другими способами по запросу (если веб-контекст уже присутствует).
  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
0 голосов
/ 13 июня 2011

Вы пытались разрешить свой репозиторий "вручную", как в этом ответе: Ninject: разрешение объекта по типу _and_ регистрационное имя / идентификатор

...