Autofac: разрешить все экземпляры типа - PullRequest
58 голосов
/ 10 сентября 2009

С учетом следующих регистраций

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

var container = builder.Build();

Я хочу разрешить все экземпляры типа I как IEnumerable (для массива или коллекции это не имеет значения).

В Виндзоре я написал бы следующее.

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

Я мигрирую из Виндзора в Autofac 1.4.4.561, но не вижу эквивалентного синтаксиса.

Ответы [ 2 ]

79 голосов
/ 10 сентября 2009

Для текущих версий Autofac: (2.0+, поэтому все, что вы должны использовать сегодня)

Вы регистрируете несколько ILoggers (например):

var builder = new ContainerBuilder();

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

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

Тогда получите все ILogger с:

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

Вам не нужно делать ничего особенного, просто попросите IEnumerable<T> нужного типа. Autofac имеет встроенную поддержку сбора данных вместе с другими адаптерами , которые могут обернуть ваши компоненты дополнительными функциями.

Это то же самое использование, что и до 2.x ImplicitCollectionSupportModule, но запеченное прямо в.

Для старых версий (0.X - 1.4)

Два способа:

1) Использовать регистрацию коллекции

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

Тогда:

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

, что дает вам IEnumerable.

или 2) Вы можете использовать модуль ImplicitCollectionSupport, который заставит код работать как новые версии Autofac:

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

Затем разрешите коллекцию ILogger, а не ищите решение всех.

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

, что снова дает вам IEnumerable.

56 голосов
/ 26 августа 2010

Обновление ради новой (2.x) версии. Все, что вам нужно сейчас:

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

Больше нет необходимости в RegisterCollection() или ImplicitCollectionSupportModule - эта функциональность поставляется из коробки.

...