简体   繁体   中英

Resolve different instances by attribute with Autofac

I would like to know if it's possible to register different instances of the same class with Autofac and then resolve the right instance with an attribute in the constructor of the consumer class.

I know we can register 2 different implementations of an interface and resolve the good one using an attribute. For instance:

 ContainerBuilder cb = new ContainerBuilder();

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

and the dependency would be used like this:

   public class HelloConsumer  { 
         public HelloConsumer([KeyFilter("EN")] IHello helloService)
         {  } 
    }

Everything works fine with this first sample.

I tried the following:

var helloEn=new Hello();
var helloFr=new Hello();    
//init properties...
helloFr.Greetings="Salut";
helloEn.Greetings="Hi";

cb.Register<Hello>(x=>helloEn).Keyed<IHello>("EN");
cb.Register<Hello>(x=>helloFr).Keyed<IHello>("FR");

which compiles fine, but during the resolution of the HelloConsumer class, the constructor's parameter "helloService" is null.

Is it possible to achieve this behavior with Autofac, or did I miss something?

(related to Autofac named registration constructor injection but not the same problem)

With the core .WithAttributeFiltering() extension. This seems to work just fine.

using System;
using Autofac;
using Autofac.Features.AttributeFilters;

public class Program
{
    public interface IHello
    {
         string Greetings { get; }
    }

    public class Hello : IHello
    {
        public string Greetings
        {
            get;
            set;
        }
    }

    public class HelloConsumer
    {
        public HelloConsumer([KeyFilter("EN")] IHello hello)
        {
            Console.WriteLine(hello.Greetings);
        }
    }

    public static void Main()
    {
        ContainerBuilder cb = new ContainerBuilder();
        cb.RegisterType<HelloConsumer>().AsSelf().WithAttributeFiltering();
        var helloEn = new Hello { Greetings = "Hi" };
        var helloFr = new Hello { Greetings = "Bonjour" };
        cb.Register<Hello>(x => helloEn).Keyed<IHello>("EN");
        cb.Register<Hello>(x => helloFr).Keyed<IHello>("FR");
        var container = cb.Build();

        container.Resolve<HelloConsumer>(); // Should write the correct greeting
    }
}

Fiddle: https://dotnetfiddle.net/3s6oFc

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM