I am trying to use named registration in the program. But example from documentation does not work. http://autofac.readthedocs.org/en/latest/advanced/keyed-services.html#named-services
public class DbLoggerModule : Autofac.Module
{
protected override void Load(Autofac.ContainerBuilder builder)
{
builder.Register<DbLogger>().Named<ILogger>("1");
}
and got compilation error: No overload for method 'Register' takes 0 arguments
I also tried the following variants:
builder.RegisterType<DbLogger>().Named<ILogger>("1");
builder.RegisterType<DbLogger>().Named<ILogger>("1").As<ILogger>();
builder.RegisterType<DbLogger>().Named<ILogger>("1").As<ILogger>();
builder.RegisterType<DbLogger>().As<ILogger>().Named<ILogger>("1");
They do not cause a compile error. But as it is not impossible to obtain a given named service:
throws an exception: The requested service '1 (Console1.ILogger)' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.
Returns an empty list
UPDATE
Part of the problem was solved. During the experiments, I have created a few interfaces with similar names. As a result, I register one interface, but resolved other.
Now this line is working:
var lll = _сontainer.ResolveNamed< ILogger >("1");
However, I can not get a complete list of classes that implement the interface:
var lll = _сontainer.ResolveNamed<ILogger>("1");
lll.Log(null); // working !
IEnumerable< ILogger >loggers=_сontainer.Resolve<IEnumerable< ILogger >>();// It returns an empty list
ALSO
When I refuse to named services, the programm begins to work:
builder.RegisterType<DbLogger>().As<ILogger>();
...
_сontainer.Resolve<IEnumerable<ILogger>>(); // working !
I suspect that we can not get a list of services registered as named. Someone can confirm this?
UPDATE 2 Here is a very simple but complete example. It does not work. Why ?
public interface ISimpleService
{
string Test();
}
public class SimpleService1 : ISimpleService
{
public string Test()
{
return "Hello World from SimpleService1";
}
}
internal class Program
{
private static void Main(string[] args)
{
var builder = new ContainerBuilder();
{
builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff");
}
IContainer container = builder.Build();
var services = container.Resolve<IEnumerable<ISimpleService>>();
Console.WriteLine(services.Count()); // 0. Why ?
}
}
You are trying to resolve ISimpleService (interface), but SimpleService1 registered only as class (because the named registration), not as interface.
Try this:
builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff").As<ISimpleService>();
or
builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff").AsImplementedInterfaces();
A fully working example:
public interface ISimpleService
{
string Test();
}
public class SimpleService1 : ISimpleService
{
public string Test()
{
return "Hello World from SimpleService1";
}
}
internal class Program
{
private static void Main(string[] args)
{
var builder = new ContainerBuilder();
{
builder.RegisterType<SimpleService1>().Named<ISimpleService>("fff").As<ISimpleService>();
}
IContainer container = builder.Build();
var services = container.Resolve<IEnumerable<ISimpleService>>();
Console.WriteLine(services.Count()); // 1.
}
}
Initial sample will work if resolve ISimpleService by name:
var services = container.ResolveNamed<IEnumerable<ISimpleService>>("fff");
Your code should work.
Are you sure you have registered your module in your container?
Ensure something like this when bootstrapping your container (assembly scanning or plain registration):
// This example being fx a console app
containerBuilder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
// Basic registration
containerBuilder.RegisterModule<LoggerModule>();
// Ensure the container is build
_container = containerBuilder.Build();
If you want to resolve a list of named (and only those, no the ones registered with a name and without, as suggested in other answers, here is what you can do:
builder.RegisterType<Foo>().Named<IFoo>("IFoo").SingleInstance();
builder.RegisterType<Foo2>().Named<IFoo>("IFoo").SingleInstance();
builder.RegisterType<Foo3>().Named<IFoo>("2").As<IFoo>().SingleInstance();
var container = builder.Build();
//Will resolve type Foo2
var foo = container.ResolveNamed<IFoo>("IFoo");
//Will resolve 2 IFoo: Foo and Foo2
var foos = container.ResolveNamed<IEnumerable<IFoo>>("IFoo");
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.