7

私は次のクラスを持っています:

using System;

interface IA { }

class A1 : IA { }

class A2 : IA { }

class B
{
    public B(IA a) {}
}

class BProvider : Provider<B>
{
    IA _a;

    public BProvider(IA a) { _a=a; }

    protected override B CreateInstance(IContext context) { return new B(_a); }
}

ninject モジュール Load() コード:

Bind<IA>().To<A1>();
Bind<IA>().To<A2>();
Bind<B>().ToProvider<BProvider>();

メインコード:

kernel.GetAll<IA>(); // works fine
kernel.GetAll<B>(); // I expect to get IEnumerable<B> with two elements, but instead of this I get an error that there are multiple bindings of IA and ninject cannot determine which to use

問題は、最後のステートメントを期待どおりに機能させることができるか、それとも他の方法で機能させることができるかということです。

4

1 に答える 1

2

Ninject は type のオブジェクトのインスタンスを作成する必要があるため、その例外がスローされますBProvider。そのためには、 への依存関係を埋める必要がありIAます。しかし、ちょっと... には 2 つのバインディングがありIAます。どちらを選択すればよいでしょうか? ...

条件付きバインディングを使用して、使用する実装を決定できます。1つの方法は次のNamedAttributeとおりです。

Bind<IA>().To<A1>();
Bind<IA>().To<A2>().Named("SecondImpl");
Bind<B>().ToProvider<BProvider>();


class BProvider : Provider<B>
{
    IA _a;

    public BProvider([Named("SecondImpl")]IA a) { _a=a; }

    protected override B CreateInstance(IContext context) { return new B(_a); }
}

この場合、A1 はNamedAttribute指定されていないデフォルトとして注入されます。

または @Remo Gloor がこの投稿で説明しているように: Ninject の構成

Bind<IA>().To<A1>();
Bind<IA>().To<A2>().WhenParentNamed("NeedSecondImpl");
Bind<B>().ToProvider<BProvider>().Named("NeedSecondImpl");

これは、コードを Ninject に関連付ける必要がなく、(1 か所で) 構成できるため、少しすっきりしています。

于 2012-11-22T21:26:20.743 に答える