Инъекционное хранилище в MembershipProvider.Initialize ()? Плохая идея? - PullRequest
1 голос
/ 17 августа 2010

Я создаю веб-приложение asp.net MVC2, используя StructureMap.Я создал собственный MembershipProvider.Я правильно инициализирую его при запуске, вызывая:

x.For<MembershipProvider>().Use(Membership.Provider);
x.For<IMembershipProvider>().Use<CPOPMembershipProvider>();

В Initialize () я имею в виду создание экземпляра репозитория, который будет использоваться для доступа к данным пользователя в базе данных.

Итак, я добавляю частную собственность в свой пользовательский MembershipProvider:

private IUserRepository userRepository;

И внутри Initialize () я вызываю:

IUserRepository userRepository = ObjectFactory.GetInstance<IUserRepository>();

Сначалаэто "хорошая практика" для создания хранилища в моем пользовательском MembershipProvider?

Во-вторых, когда я его реализую, мне кажется, что я не могу получить доступ к любой конфигурации StructureMap, которая была правильно настроена в global.asax.Когда я вызываю Debug.WriteLine (ObjectFactory.WhatDoIHave ()) непосредственно перед приведенной выше строкой GetInstance (), никакие данные конфигурации отсутствуют (что я вижу из той же строки Debug, помещенной в global.asax), и я получаюНе определен экземпляр по умолчанию для PluginFamily CPOP.Domain.Contracts.Repositories.IUserRepository "ошибка при вызове GetInstance ().Это почему?Похоже, у меня есть другой контейнер внутри MembershipProvider.

Ответы [ 3 ]

3 голосов
/ 19 августа 2010

Завершается с помощью инъекции в сеттер в StructureMap.Свойство userRepository в пользовательском MembershipProvider можно настроить, вызвав:

CPOPMembershipProvider member =
     (CPOPMembershipProvider) Membership.Providers["CPOPMembershipProvider"];
ObjectFactory.Configure(x =>
{
    ...
    x.For<MembershipProvider>().Use(Membership.Provider);
    x.For<IMembershipProvider>().TheDefault.Is.Object(member);
    ...
    x.For<IPatientRepository>().Use<PatientRepository>();
    x.For<IUserRepository>().Use<UserRepository>();
    x.SetAllProperties(y => { y.OfType<IUserRepository>(); });
    ...
}); 

И затем вызвав BuildUp () для целевого экземпляра.Я делаю это в Application_Start (), после того как все реестры были вызваны, а StructureMap имеет все данные конфигурации.

ObjectFactory.BuildUp(Membership.Providers["CPOPMembershipProvider"]);

Готово.

0 голосов
/ 08 февраля 2012

Поставщик членства в основном одноэлементный, что означает, что ASP.NET будет создавать только один экземпляр.Так что не храните ничего в приватных полях / свойствах, если вы не хотите сюрпризов в работе, когда два потока используют одного и того же поставщика членства одновременно.

Мне нужно было только реализовать ValidateUser, так как мы не используем никаких другихметоды, и я сделал это так:

public bool ValidateUser(string userName, string password)
{
    var session = DependencyResolver.Curret.GetService<ISession>();

    using (session)
    {
        using (var tx = session.BeginTransaction())
        {
            // load the user from db and validate the password etc.
            tx.Commit();
        }
    }
}

Конечно, вам нужно настроить DependencyResolver, StructureMap и т. д., но дело в том, что ISession не хранится в приватном поле / свойстве.

0 голосов
/ 07 февраля 2012

Большое спасибо за ответ на ваш вопрос ... это было именно то, что я искал.

Немного измененный для меня, трюк настраивал все через ObjectFactory (как и выше) и использовал контейнер этого ObjectFactory для DependencyResolver:

UserMembershipProvider provider = 
 (UserMembershipProvider)Membership.Providers["UserMembershipProvider"];

ObjectFactory.Configure(x =>
{
    x.For<ISessionFactory>()
        .Singleton()
        .Use(() => NHibernateInitializer.Initialize().BuildSessionFactory());
    x.For<IEntityDuplicateChecker>().Use<EntityDuplicateChecker>();
    x.For(typeof(IRepository<>)).Use(typeof(Repository<>));
    x.For(typeof(IRepositoryWithTypedId<,>)).Use(typeof(RepositoryWithTypedId<,>));
    x.SetAllProperties(y =>
    {
        y.WithAnyTypeFromNamespaceContainingType<IEntityDuplicateChecker>();
    });
});

ObjectFactory.BuildUp(provider);
DependencyResolver.SetResolver(
  new StructureMapDependencyResolver(ObjectFactory.Container));

Таким образом, все работает с точки зрения фабрики контроллеров, и MembershipProvider «создается» по факту (поскольку он уже был создан до Application_Start благодаря .NET.) Этот код выше вызывается из Application_Start.

...