11

Funq IoC コンテナーは、型のすべての登録の解決をサポートしていますか? 次のいずれかのようなもの:

IEnumerable<IFoo> foos = container.Resolve<IEnumerable<IFoo>>();
IEnumerable<IFoo> foos = container.ResolveAll<IFoo>();
4

2 に答える 2

9

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の使用に固有のものではありません。

于 2012-01-12T10:27:42.973 に答える