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>
できます。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
ただし、が再利用される場合、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の使用に固有のものではありません。