7

を使用してプロパティを注入しようとしていますninject。以下のモジュールの 2 つのバインディングを考えると、が に注入されるninjectと予想されます。ただし、注入される型は考慮されていないようで、ターゲットの宣言型 (この場合はプロパティ) のみが考慮されます。ConcreteDependencyB
WhenInjectedInto

私が期待した動作を達成する方法はありますか?

static void Main(string[] args)
{
    var kernel = new StandardKernel(new TestModule());
    var b = kernel.Get<B>();
    var c = kernel.Get<C>();
}

class TestModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDependency>().To<EmptyDependency>();
        Bind<IDependency>().To<ConcreteDependency>().WhenInjectedInto<B>();
    }
}

abstract class A
{
    [Inject]
    public IDependency Dependency { get; set; }
}

class B : A {}

class C : A {}

interface IDependency {}

class EmptyDependency : IDependency { }

class ConcreteDependency : IDependency { }
4

2 に答える 2

8

可能であれば、プロパティ注入の代わりにコンストラクター注入を使用する必要があります。オブジェクトの構築に必要な依存関係が明示的になり、コンストラクターによるオブジェクトの署名がより表現力豊かになるため、これはより優れた手法であり、Mark Seeman によって推奨されています。コードは次のようになります。

    abstract class A
    {
        public IDependency Dependency { get; private set; }

        public A (IDependency dependency)
        {
            Dependency = dependency;
        }

    }

    class B : A
    {
        public B (IDependency dependency)
            : base(dependency)
        {

        }
    }

    class C : A
    {
        public C (IDependency dependency)
            : base(dependency)
        {

        }
    }

    interface IDependency { }

    class EmptyDependency : IDependency { }

    class ConcreteDependency : IDependency { }

構成は、例と同じになります。次のテストはパスします

    [Test]
    public void TestSpecificBindingToObjectB()
    {
        var kernel = new StandardKernel(new TestModule());
        var b = kernel.Get<B>();
        var c = kernel.Get<C>();

        Assert.AreNotEqual(b.Dependency.GetType(), c.Dependency.GetType());
        Assert.AreEqual(typeof(ConcreteDependency), b.Dependency.GetType());
    }

デフォルトの実装にオプションの依存関係があり、クラスを属性で装飾しても問題ない場合はInject、次のようにリクエストから親情報を取得できます。

class TestModule : NinjectModule
{
    public override void Load()
    {
        Bind<IDependency>().To<EmptyDependency>();
        Bind<IDependency>().To<ConcreteDependency>().When(req =>req.ParentContext.Request.Service == typeof(B));
    }
}

次に、プロパティ注入を使用したクラス階層に対して、上記と同じテストに合格します。

于 2012-11-04T20:50:44.070 に答える
4

具体的なタイプをチェックするためParentContext.Plan.Typeに、IRequestインターフェイスで使用できます。これにより、期待どおりの動作が得られるはずですWhenInjectedInto。例えば:

When(req => req.ParentContext.Plan.Type == typeof(B))
于 2012-11-07T01:37:20.860 に答える