2009-09-10 16 views
50

Es gelten folgende AnmeldungenAutofac: Lösen Sie alle Instanzen einer Art

builder.Register<A>().As<I>(); 
builder.Register<B>().As<I>(); 
builder.Register<C>().As<I>(); 

var container = builder.Build(); 

ich alle Instanzen des Typs zu lösen suche ich als IEnumerable (Array oder Sammlung es keine Rolle spielt).

In Windsor hätte ich folgendes geschrieben.

foreach(I i in container.ResolveAll<I>()) 
{ 
... 
} 

Ich migriere von Windsor zu Autofac 1.4.4.561, kann aber die entsprechende Syntax nicht sehen.

+0

Möchten Sie teilen, warum Sie von Windsor nach Autofac umziehen? –

+0

Die Sache, die ich mit Autofac wirklich mag, ist die Fähigkeit, die dynamische Bauteilkonstruktion durch Lamda-Ausdrücke auszudrücken.Durch die Verwendung von Ausdrücken im Gegensatz zum Autowiring gibt es weniger Raum für Missverständnisse darüber, was der Container "macht", wenn er einen Typ auflöst (Anmerkung: Autofac unterstützt das Autowiren, wenn Sie bevorzugen). Schließlich ist die Windsor-API so groß geworden, dass sie jede Möglichkeit berücksichtigt, die den Eindruck von Komplexität erweckt, wenn IOC als Konzept eigentlich recht einfach ist. Ich sage nicht, dass ich Windsor nie wieder benutzen werde, nur die anderen Optionen auszuprobieren. – crowleym

+1

Ich habe überlegt, von Windsor nach Autofac zu ziehen. Windsors API ist verwirrend. – Amy

Antwort

69

Für aktuelle versons von Autofac: (2.0+, so etwas sollten Sie heute verwenden)

Sie registrieren mehrere ILoggers (zum Beispiel):

var builder = new ContainerBuilder(); 

builder.Register<ConsoleLogger>() 
    .As<ILogger>(); 

builder.Register<EmailLogger>() 
    .As<ILogger>() 
    .PreserveExistingDefaults(); //keeps console logger as the default 

Dann werden alle ILogger s erhalten:

var loggers = container.Resolve<IEnumerable<ILogger>>(); 

Sie brauchen nichts besonderes zu tun, fragen Sie einfach für eine IEnumerable<T> des gewünschten Typs. Autofac verfügt standardmäßig über die Unterstützung für die Sammlung, zusammen mit anderen adapters, die Ihre Komponenten mit zusätzlichen Funktionen umhüllen können. .

Dies ist die gleiche Nutzung wie die Pre-2.x ImplicitCollectionSupportModule, aber gebacken rechts in

Für alte Versionen (0.X - 1,4)

Zwei Möglichkeiten:

1) Verwenden der Sammlung Registrierung

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>>(); 

Dann:

var loggers = container.Resolve<IEnumerable<ILogger>>(); 

was gibt Ihnen ein IEnumerable.

oder 2) können Sie das ImplicitCollectionSupport Modul verwenden, die den Code arbeiten wie neuere Versionen von Autofac machen:

builder.RegisterModule(new ImplicitCollectionSupportModule()); 
builder.Register(component1).As<ILogger>; 
builder.Register(component2).As<ILogger>; 

Dann eine Sammlung von ILogger lösen, anstatt für die Lösung alle suchen.

var loggers = container.Resolve<IEnumerable<ILogger>>(); 

was gibt Ihnen ein IEnumerable, wieder.

+0

Perfekt. Ging nach Option eins, da es effizienter scheint, weil der Container "weiß", was in die Sammlung zu legen ist. Die zweite Option iteriert bei jeder Registrierung in der Containerhierarchie nach übereinstimmenden Typen. – crowleym

+0

@ philip-rieck Hallo, was bedeutet container.resolve in Autofac ?. Wenn Sie nicht Autofac verwenden, auf welche Weise können Sie Illogger-Schnittstelle deklarieren? Danke ... –

+1

@sebastian_h Wenn Sie nicht Autofac verwenden, wird diese Antwort keine Bedeutung für Sie haben. Vielleicht möchten Sie stattdessen hier nachsehen: http://stackoverflow.com/questions/5646820/logger-wrapper-best-practice –

54

Ein Update für die neue (2.x) Version. Alles, was Sie jetzt brauchen, ist:

container.Resolve<IEnumerable<I>>(); 

Es besteht kein Bedarf mehr für RegisterCollection() oder ImplicitCollectionSupportModule - diese Funktionalität aus der Box kommt.

Verwandte Themen