Funq IoC コンテナーは、型のすべての登録の解決をサポートしていますか? 次のいずれかのようなもの:
IEnumerable<IFoo> foos = container.Resolve<IEnumerable<IFoo>>();
IEnumerable<IFoo> foos = container.ResolveAll<IFoo>();
Funq IoC コンテナーは、型のすべての登録の解決をサポートしていますか? 次のいずれかのようなもの:
IEnumerable<IFoo> foos = container.Resolve<IEnumerable<IFoo>>();
IEnumerable<IFoo> foos = container.ResolveAll<IFoo>();
Funqにはメソッドがありませんが、質問に示されているように、をResolveAll登録しIEnumerable<IFoo>て解決するだけです。Resolve<IEnumerable<IFoo>>()
ただし、一般的には、コレクションのコンテナーを要求せず、代わりにコンポジットを使用することをお勧めします。IFooこのようにして、依存関係のコンシューマーにリストの反復を強制する代わりに、依存関係としてを挿入することができます。代わりにIFoo、コンポジット内のインスタンスのリストをループするコードを埋め込みます。これにより、コードがDRYforeach (var foo in foos)に保たれ、アイテムの反復方法に変更を加える必要がある場合に、アプリケーション全体に散在する(可能性のある)数十のステートメントを実行する必要がなくなります。または、別の言い方をすれば、すべてを繰り返す方法を知ることは消費者の責任ではありませんIFoo。
IFooコンポジットの例を次に示します。
// 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>できます。CompositeFooIFoo
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ただし、が再利用される場合、Foo2実際には一時的なものではありませんが、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);
}
}
}
これで、コンストラクターにいくつかのsを挿入する代わりにIFoo、コンストラクターにいくつかのラムダを挿入できます。
container.Register<IFoo>(c => new CompositeFoo(
() => c.Resolve<Foo1>(),
() => c.Resolve<Foo2>(),
() => c.Resolve<Foo3>()));
CompositeFooこれにより、が呼び出されるたびFooThatThingに、コンテナに新しいIFooインスタンスが照会されるようになります。これによりFooThatThing、同じコンシューマーから複数回呼び出すことができCompositeFoo、シングルトンとして登録することもできます。
このアドバイスは、すべてのコンテナーと依存性注入に一般的に当てはまり、Funqの使用に固有のものではありません。