Autofac: risolve tutte le istanze di un tipo
Domanda
Date le seguenti registrazioni
builder.Register<A>().As<I>();
builder.Register<B>().As<I>();
builder.Register<C>().As<I>();
var container = builder.Build();
Sto cercando di risolvere tutte le istanze di tipo I come IEnumerable
(Array o Collection non importa).
In Windsor avrei scritto quanto segue.
foreach(I i in container.ResolveAll<I>())
{
...
}
Sto migrando da Windsor ad Autofac 1.4.4.561 ma non riesco a vedere la sintassi equivalente.
Soluzione
Per i versetti attuali di Autofac: (2.0+, quindi tutto ciò che dovresti usare oggi)
Hai registrato più ILoggers
(ad esempio):
var builder = new ContainerBuilder();
builder.Register<ConsoleLogger>()
.As<ILogger>();
builder.Register<EmailLogger>()
.As<ILogger>()
.PreserveExistingDefaults(); //keeps console logger as the default
Quindi ottieni tutti ILogger
s:
var loggers = container.Resolve<IEnumerable<ILogger>>();
Non devi fare nulla di speciale, basta chiedere un IEnumerable<T>
del tipo desiderato. Autofac ha il supporto per la raccolta pronto all'uso, insieme ad altri adattatori che può avvolgere i tuoi componenti con funzionalità aggiuntive.
Questo è lo stesso utilizzo del modulo ImplicitCollectionSupportModule pre-2.x, ma inserito correttamente.
Per le versioni precedenti (0.X - 1.4)
Due modi:
1) Utilizza la registrazione della raccolta
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>>();
Quindi:
builder.RegisterModule(new ImplicitCollectionSupportModule());
builder.Register(component1).As<ILogger>;
builder.Register(component2).As<ILogger>;
che ti dà un IEnumerable.
o 2) È possibile utilizzare il modulo ImplicitCollectionSupport, che farà funzionare il codice come le versioni più recenti di Autofac:
<*>Quindi risolvi una raccolta di ILogger piuttosto che cercare di risolvere tutto.
<*>che ti dà di nuovo un IEnumerable.
Altri suggerimenti
Un aggiornamento per il bene della nuova versione (2.x). Tutto ciò che serve ora è:
container.Resolve<IEnumerable<I>>();
Non è più necessario RegisterCollection()
o ImplicitCollectionSupportModule
: questa funzionalità è pronta all'uso.