Autofac: resuelve todas las instancias de un tipo
Pregunta
Dados los siguientes registros
builder.Register<A>().As<I>();
builder.Register<B>().As<I>();
builder.Register<C>().As<I>();
var container = builder.Build();
Estoy buscando resolver todas las instancias de tipo I como IEnumerable
(matriz o colección, no importa).
En Windsor, habría escrito lo siguiente.
foreach(I i in container.ResolveAll<I>())
{
...
}
Estoy migrando de Windsor a Autofac 1.4.4.561 pero no puedo ver la sintaxis equivalente.
Solución
Para versons actuales de Autofac: (2.0+, entonces cualquier cosa que deba usar hoy)
Usted registra múltiples ILoggers
(por ejemplo):
var builder = new ContainerBuilder();
builder.Register<ConsoleLogger>()
.As<ILogger>();
builder.Register<EmailLogger>()
.As<ILogger>()
.PreserveExistingDefaults(); //keeps console logger as the default
Luego obtenga todos los ILogger
s:
var loggers = container.Resolve<IEnumerable<ILogger>>();
No necesita hacer nada especial, solo solicite un IEnumerable<T>
del tipo deseado. Autofac tiene soporte de colección listo para usar, junto con otros adaptadores que puede envolver sus componentes con funcionalidad adicional.
Este es el mismo uso que el ImplicitCollectionSupportModule anterior a 2.x, pero integrado directamente.
Para versiones anteriores (0.X - 1.4)
Dos formas:
1) Usar el registro de la colección
var builder = new ContainerBuilder();
builder.RegisterCollection<ILogger>()
.As<IEnumerable<ILogger>>();
builder.Register<ConsoleLogger>()
.As<ILogger>()
.MemberOf<IEnumerable<ILogger>>();
builder.Register<EmailLogger>()
.As<ILogger>()
.MemberOf<IEnumerable<ILogger>>();
Entonces:
builder.RegisterModule(new ImplicitCollectionSupportModule());
builder.Register(component1).As<ILogger>;
builder.Register(component2).As<ILogger>;
que le da un IEnumerable.
o 2) Puede usar el módulo ImplicitCollectionSupport, que hará que el código funcione como las versiones más nuevas de Autofac:
<*>Luego resuelva una colección de ILogger en lugar de buscar resolver todos.
<*>que te da un IEnumerable, de nuevo.
Otros consejos
Una actualización por el bien de la nueva versión (2.x). Todo lo que necesitas ahora es:
container.Resolve<IEnumerable<I>>();
Ya no hay necesidad de RegisterCollection()
o ImplicitCollectionSupportModule
: esta funcionalidad viene de fábrica.