Does Autofac support specifying the registration name in the components' constructors?
Example: Ninject's NamedAttribute
.
Register by Type var builder = new ContainerBuilder(); builder. RegisterType<ConsoleLogger>(); builder. RegisterType(typeof(ConfigReader)); When using reflection-based components, Autofac automatically uses the constructor for your class with the most parameters that are able to be obtained from the container.
Autofac is an addictive Inversion of Control container for . NET Core, ASP.NET Core, . NET 4.5. 1+, Universal Windows apps, and more.
From Visual Studio, you can get it via NuGet. The package name is Autofac. Alternatively, the NuGet package can be downloaded from the GitHub repository (https://github.com/autofac/Autofac/releases).
RegistrationExtensions. AsImplementedInterfaces MethodSpecifies that a type from a scanned assembly is registered as providing all of its implemented interfaces.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With