Автофас:Разрешить все экземпляры типа

StackOverflow https://stackoverflow.com/questions/1406148

  •  05-07-2019
  •  | 
  •  

Вопрос

Учитывая следующие регистрации

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>())
{
 ...
}

Я перехожу с Windsor на Autofac 1.4.4.561, но не вижу эквивалентного синтаксиса.

Это было полезно?

Решение

Для текущих версий 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

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

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

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

Это то же использование, что и ImplicitCollectionSupportModule до 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.

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top