Funq не имеет метода ResolveAll
, но вы можете просто зарегистрировать IEnumerable<IFoo>
и разрешить его с помощью Resolve<IEnumerable<IFoo>>()
, как показано в вашем вопросе.
В целом, однако, лучше не для запроса контейнера для коллекций, но вместо этого используйте composites .Таким образом, вы можете просто внедрить IFoo
в качестве зависимости, вместо того, чтобы заставлять потребителей этой зависимости повторять список.Вместо этого вы встраиваете код, который зацикливает список IFoo
экземпляров внутри композита.Это сохраняет ваш код DRY и не вынуждает вас проходить (возможные) десятки foreach (var foo in foos)
операторов, разбросанных по всему приложению, когда необходимо внести изменения в способ итерации элементов.Или позвольте мне выразить это иначе: потребитель не обязан знать, как перебирать все IFoo
s.
Вот пример IFoo
Composite:
// A composite is something that implements an interface
// (in this case IFoo) and wraps a list of items of that
// same interface.
public class FooComposite : IFoo
{
private readonly IEnumerable<IFoo> foos;
public FooComposite(params IFoo[] foos)
{
this.foos = foos;
}
void IFoo.FooThatThing(IBar bar)
{
foreach (var foo in this.foos)
{
foo.FooThatThing(bar);
}
}
}
Вместо регистрации IEnumerable<IFoo>
вы можете зарегистрировать CompositeFoo
как IFoo
:
container.Register<IFoo>(c => new CompositeFoo(
new Foo1(), new Foo2(), new Foo3()));
Теперь вы можете позволить контейнеру вводить CompositeFoo
в потребителях, которые принимаютIFoo
аргумент, который заставляет их не осознавать, что они на самом деле имеют дело со списком IFoo
элементов.
ОБНОВЛЕНИЕ :
Используя этот составной шаблон, выможет легко контролировать срок службы каждого элемента IFoo
.Это просто вопрос обратного вызова в контейнер.С Funq это выглядело бы так:
container.Register<IFoo>(c => new CompositeFoo(
c.Resolve<Foo1>(),
c.Resolve<Foo2>(),
c.Resolve<Foo3>()));
Таким образом, вы можете зарегистрировать Foo1
как синглтон и Foo2
как переходный процесс, например.Однако при повторном использовании CompositeFoo
1044 * на самом деле не будет кратковременным, но это просто вопрос изменения CompositeFoo
и его регистрации для решения этой проблемы.Например, вы можете изменить CompositeFoo
на следующее:
public class FooComposite : IFoo
{
private readonly Func<IFoo>[] fooFactories;
public FooComposite(params Func<IFoo>[] fooFactories)
{
this.fooFactories = fooFactories;
}
void IFoo.FooThatThing(IBar bar)
{
foreach (var fooFactory in this.fooFactories)
{
var foo = fooFactory();
foo.FooThatThing(bar);
}
}
}
Теперь вместо того, чтобы вводить в конструктор несколько IFoo
с, мы можем вставить в него несколько лямбд:
container.Register<IFoo>(c => new CompositeFoo(
() => c.Resolve<Foo1>(),
() => c.Resolve<Foo2>(),
() => c.Resolve<Foo3>()));
Это гарантирует, что при каждом вызове CompositeFoo
FooThatThing
контейнер запрашивается для новых IFoo
экземпляров.Это позволяет многократному вызову FooThatThing
одним и тем же потребителем и даже позволяет регистрировать CompositeFoo
как singleton.
Этот совет применим для всех контейнеров и внедрения зависимостей в целом и не относится киспользование Funq.