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. 但是片刻...... 有两个绑定IA,我应该选择哪个?...

您可以使用一些条件绑定来决定应该使用哪个实现。一种方法是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 并且可以让它配置(在一个地方)。

于 2012-11-22T21:26:20.743 回答