2009-09-10 15 views
50

otrzymuje następujące rejestracjeAutofac: rozwiązać wszystkie wystąpienia danego typu

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

var container = builder.Build(); 

szukam rozwiązać wszystkie instancje typu I jako IEnumerable (tablica lub Collection to nie ma znaczenia).

W Windsor napisałbym poniżej.

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

Przeprowadzam migrację z Windsor do wersji Autofac 1.4.4.561, ale nie widzę równoważnej składni.

+0

Każdy powód, dla którego chcesz się podzielić, dlaczego przenosisz się z Windsor do Autofac? –

+0

Rzeczą, która bardzo podoba mi się w Autofac jest możliwość wyrażenia dynamicznej konstrukcji komponentów za pomocą wyrażeń lamda.Używając wyrażeń w przeciwieństwie do autowirowania, jest mniej miejsca na niezrozumienie tego, co kontener "robi", kiedy rozwiązuje typ (uwaga: autofac obsługuje autowiring, jeśli wolisz). W końcu interfejs API Windsor stał się tak wielki, że w każdym przypadku stwarza wrażenie złożoności, kiedy IOC jako koncepcja jest całkiem prosta. Nie mówiąc, że nigdy więcej nie użyję Windsora, tylko wypróbuję inne opcje. – crowleym

+1

Rozważałem przejście z Windsor do Autofac. Interfejs API Windsora jest mylący. – Amy

Odpowiedz

69

Dla obecnych versons z Autofac: (2.0+, więc coś, co powinno być przy użyciu dzisiaj)

zarejestrować wiele ILoggers (na przykład):

var builder = new ContainerBuilder(); 

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

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

Następnie dostać wszystkie ILogger s:

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

Nie musisz robić nic specjalnego, po prostu zapytaj o IEnumerable<T> pożądanego typu. Autofac oferuje wsparcie w zakresie zbierania po wyjęciu z pudełka, wraz z innymi adapters, które mogą owijać twoje komponenty dodatkową funkcjonalnością. .

To samo użycie jako ImplicitCollectionSupportModule pre-2.x, ale upieczone tuż

Dla starszych wersji (0.x - 1,4)

dwa sposoby:

1) Za pomocą rejestracji zbiórki

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

wówczas:

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

co daje niezliczoną liczbę.

lub 2) Można użyć modułu ImplicitCollectionSupport, które uczynią pracę kodu jak nowsze wersje Autofac:

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

Następnie rozwiązać zbiór ILogger zamiast szuka rozwiązania wszystkich.

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

który daje ponownie niezliczoną liczbę.

+0

Idealny. Poszedł na opcję pierwszą, ponieważ wydaje się bardziej skuteczny, ponieważ kontener "wie", co umieścić w kolekcji. Druga opcja powoduje iterację, chociaż każda rejestracja w hierarchii kontenera szuka pasujących typów. – crowleym

+0

@ philip-rieck hi, co to znaczy container.resolve w autofac ?. Jeśli nie używasz autofac, w jaki sposób możesz zadeklarować interfejs Iloggera? dziękuję ... –

+1

@sebastian_h jeśli nie używasz autofac, ta odpowiedź nie będzie miała dla ciebie znaczenia. Zamiast tego możesz zajrzeć tutaj: http://stackoverflow.com/questions/5646820/logger-wrapper-best-practice –

54

Aktualizacja ze względu na nową wersję (2.x). Wszystko, co musisz teraz jest:

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

Nie ma już potrzeba RegisterCollection() lub ImplicitCollectionSupportModule - funkcjonalność ta wychodzi z pudełka.

Powiązane problemy