How do I inject a repository into a custom MembershipProvider using AutoFac

假装没事ソ 提交于 2019-12-06 12:57:41

No. It's not possible.

The DependencyResolver is not used for the providers (roles/membership) etc.

I've made a membership provider which uses DependencyResolver internally. All you need to do is to implement IAccountRepository and register it in your container.

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

It's an old post, so i'll just post here my solution as I struggle with it a bit myself.

public class AutofacBootstrapperImp : AutofacBootstrapper

In your autofac builder setup include register for your interface

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

public class CustomMembershipProvider : MembershipProvider

Overload init method and use autofac scope to resolve your type

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

You should also register the IRepository<User>. But to do that you need to access your custom provider by its concrete type.

So something like this:

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

That could be made nicer (avoiding casts by registering your implementation) as follows, but not sure on how it then fits in with ASP.NET and its management of provider lifecycles:

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

EDIT:

but from a design standpoint, it looks like your MyMembership class has a dependency on the IRepository<User>, therefor something like this is probably best:

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

That way the IRepository will be injected into the MyMembership as needed, but also be available for direct consumption by other components, and they all have the lifetime management handled by Autofac.

This scenario is entirely possible. In my Bootstrapper.cs class, I just inject the properties into the providers as such:

        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

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

I also have the following:

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

however I'm not entirely sure if it's even necessary. I believe the Registers are there in case you want to inject the provider into a type.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!