Как добавить репозиторий в пользовательский MembershipProvider с помощью AutoFac - PullRequest
2 голосов
/ 22 февраля 2012

Я создал пользовательский поставщик членства

public class MyMembership : MembershipProvider
{
    private IRepository<User> Repo;
}

Я выяснил, как добавить MyMembership с помощью autofac:

builder.Register(c => Membership.Provider);

Однако, это не сработает, если у меня есть конструктор, которыйпринимает IRepository (он вызывает только конструктор без параметров.) Я попытался сделать переход от закрытого поля к общему свойству и вызвать:

builder.Register(c => Membership.Provider).AutoWireProperties();

Проблема в том, что MembershipProvider не имеет свойства Repo, этотолько мой класс.

В настоящее время я ничего не вводил, а просто создал пустой конструктор, в котором я просто создаю новый экземпляр моего репо.Но это усложняет тестирование.

Итак, есть ли способ, с помощью которого я могу использовать AutoFac для ввода моего членства и заставить его использовать введенный репо?

Ответы [ 4 ]

2 голосов
/ 12 января 2014

Это старый пост, поэтому я просто опубликую здесь свое решение, так как сам немного с этим борюсь.

открытый класс AutofacBootstrapperImp: AutofacBootstrapper

В настройках вашего autofac builder включите регистрацию для вашего интерфейса

builder.RegisterType<YourRepo>().As<IRepository<User>>().SingleInstance();

открытый класс CustomMembershipProvider: MembershipProvider

Перегрузите метод init и используйте область действия autofac для разрешения вашего типа

private IRepository<User> Repo;

    public override void Initialize(string name, NameValueCollection config)
    {
        // use autoface scope to resole service
        using (var scope = AutofacBootstrapper.Container.BeginLifetimeScope())
        {
            Repo = scope.Resolve<IRepository<User>>();
        }

        if (config == null)
            throw new ArgumentNullException("config");

        // Initialize the abstract base class.
        base.Initialize(name, config);
    }
2 голосов
/ 22 февраля 2012

Нет. Это невозможно.

DependencyResolver не используется для провайдеров (роли / членство) и т. Д.

Я сделал провайдера, который использует DependencyResolver для внутреннего использования. Все, что вам нужно сделать, это реализовать IAccountRepository и зарегистрировать его в своем контейнере.

http://blog.gauffin.org/2011/09/a-more-structured-membershipprovider/

1 голос
/ 22 февраля 2012

Вы также должны зарегистрировать IRepository<User>.Но для этого вам нужно получить доступ к своему пользовательскому провайдеру по его конкретному типу.

Так что-то вроде этого:

builder.Register( c => Membership.Provider );
builder.Register( c => ((MyMembership) Membership.Provider).Repo );

Это может быть лучше (избегая приведения путем регистрации вашей реализации) какследует, но не уверен, как он вписывается в ASP.NET и управляет жизненными циклами провайдера:

builder.RegisterType<MyMembership>();
builder.Register( c => c.Resolve<MyMembership>() ).As<MembershipProvider>();
builder.Register( c => c.Resolve<MyMembership>().Repo );

РЕДАКТИРОВАТЬ:

но с точки зрения дизайна, он выглядит как ваш *Класс 1012 * имеет зависимость от IRepository<User>, поэтому что-то вроде этого, вероятно, лучше:

builder.RegisterType<YourRepositoryImplementation>().As<IRepository<User>>();
builder.RegisterType<MyMembership>();
builder.Register( c => c.Resolve<MyMembership>() ).As<MembershipProvider>();

Таким образом, IRepository будет вводиться в MyMembership по мере необходимости, но также будет доступен для непосредственного использованиядругие компоненты, и все они имеют управление временем жизни, осуществляемое Autofac.

0 голосов
/ 02 августа 2012

Этот сценарий вполне возможен. В моем классе Bootstrapper.cs я просто внедряю свойства в провайдеры как таковые:

        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        var lifetimeScope = DependencyResolver.Current.GetService<ILifetimeScope>();
        lifetimeScope.InjectProperties(Membership.Provider);
        lifetimeScope.InjectProperties(Roles.Provider);

У меня также есть следующее:

        builder.Register(context => Membership.Provider).ExternallyOwned();
        builder.Register(context => Roles.Provider).ExternallyOwned();

однако я не совсем уверен, нужно ли это вообще. Я считаю, что Register есть, если вы хотите внедрить провайдера в тип.

...