Ninject注入界面的多重绑定

时间:2012-07-26 19:51:04

标签: c# .net ninject

我有以下课程:

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

所以问题是我是否可以使最后一个语句按预期工作或以其他方式进行?

1 个答案:

答案 0 :(得分:2)

它将抛出该异常,因为Ninject需要创建类型为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在这篇文章中解释:Configuring Ninject

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

这有点干净,因为您不必将代码绑定到Ninject,只需在配置上(在一个地方)。