Автофас:Разрешить все экземпляры типа
Вопрос
Учитывая следующие регистрации
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
Тогда получите все ILogger
s:
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
- эта функция поставляется «из коробки».