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

柔情痞子 提交于 2020-01-13 19:13:08

问题


I created a custom membership provider

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

I figured out how to inject MyMembership using autofac:

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

However, this doesn't work if I have a constructor that takes an IRepository (it only calls the parameterless constructor.) I tried doing changing from a private field to a public property and calling:

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

The problem is, MembershipProvider doesn't have a Repo property, it's only my class.

For the time being, I've not injected anything, and just created an empty constructor where I simply create a new instance of my Repo. But it makes it harder for testing.

So, is there any way that I can use AutoFac to inject my MyMembership, and have it use the injected Repo?


回答1:


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/




回答2:


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



回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/9396541/how-do-i-inject-a-repository-into-a-custom-membershipprovider-using-autofac

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