Autofac named registration constructor injection

那年仲夏 提交于 2020-01-01 08:49:31

问题


Does Autofac support specifying the registration name in the components' constructors?

Example: Ninject's NamedAttribute.


回答1:


You need to use the Autofac.Extras.Attributed package on top to achieve this

So let's say you have one interface and two classes:

public interface IHello
{
    string SayHello();
}

public class EnglishHello : IHello
{
    public string SayHello()
    {
        return "Hello";
    }
}

public class FrenchHello : IHello
{
    public string SayHello()
    {
        return "Bonjour";
    }
}

Then you have a consumer class, which in you want to select which instance is injected:

public class HelloConsumer
{
    private readonly IHello helloService;

    public HelloConsumer([WithKey("EN")] IHello helloService)
    {
        if (helloService == null)
        {
            throw new ArgumentNullException("helloService");
        }
        this.helloService = helloService;
    }

    public string SayHello()
    {
        return this.helloService.SayHello();
    }
}

Registering and resolving:

ContainerBuilder cb = new ContainerBuilder();

cb.RegisterType<EnglishHello>().Keyed<IHello>("EN");
cb.RegisterType<FrenchHello>().Keyed<IHello>("FR");
cb.RegisterType<HelloConsumer>().WithAttributeFilter();
var container = cb.Build();

var consumer = container.Resolve<HelloConsumer>();
Console.WriteLine(consumer.SayHello());

Do not forget the AttributeFilter when you register such a consumer, otherwise resolve will fail.

Another way is to use a lambda instead of attribute.

cb.Register<HelloConsumer>(ctx => new HelloConsumer(ctx.ResolveKeyed<IHello>("EN")));

I find the second option cleaner since you also avoid to reference autofac assemblies in your project (just to import an attribute), but that part is a personal opinion of course.




回答2:


        var builder = new ContainerBuilder();

        builder.RegisterType<LiveGoogleAnalyticsClass>().Named<IGoogleAnalyticsClass>("Live");
        builder.RegisterType<StagingGoogleAnalyticsClass>().Named<IGoogleAnalyticsClass>("Staging");
        var container = builder.Build();

        var liveGAC = container.ResolveNamed<IGoogleAnalyticsClass>("Live");
        var stagingGAC = container.ResolveNamed<IGoogleAnalyticsClass>("Staging");

This just requires the standard Autofac dll, no reference of the Autofac.Extras.Attributed assembly is needed. I'm currently using Autofac 3.5.0 due to legacy requirements.



来源:https://stackoverflow.com/questions/23986395/autofac-named-registration-constructor-injection

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