Ninject注入接口的多重绑定

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

所以问题是我是否可以使最后一条语句按预期工作,或者用其他方法实现?
1个回答

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); }
}

在这种情况下,如果未指定NamedAttribute,则A1将作为默认值注入。
或者像@Remo Gloor在这篇文章中解释的那样:配置Ninject
Bind<IA>().To<A1>();
Bind<IA>().To<A2>().WhenParentNamed("NeedSecondImpl");
Bind<B>().ToProvider<BProvider>().Named("NeedSecondImpl");

这样更为简洁,因为您不必将代码与Ninject联系在一起,可以将其放在配置中(一个地方)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接