Ninject 2.0 – 绑定到多次使用相同接口的对象?
考虑以下:
public Something(IInterface concreteObjectOne, IInterface concreteObjectTwo) { this.concreteObjectOne = concreteObjectOne; this.concreteObjectTwo = concreteObjectTwo; }
如何设置与Ninject绑定此类绑定? 我试着谷歌搜索这个词,但由于我不知道这叫做什么我不能,也无法在Wiki上找到任何关于此的内容。
编辑 :
我相信这被称为基于约定的绑定,如此处所述。 但是,此文档适用于版本1.0和2.0没有Only
方法。 我希望这可以在没有属性的情况下实现 – 使用名称约定或类似的东西。
除了使用“Only”方法之外,本文还通过为注入的对象指定不同的属性来提出另一种解决方案。
例:
public class ObjectOneAttribute : Attribute { } public class ObjectTwoAttribute : Attribute { }
然后
public Something([ObjectOneAttribute] IInterface concreteObjectOne, [ObjectTwoAttribute] IInterface concreteObjectTwo) { this.concreteObjectOne = concreteObjectOne; this.concreteObjectTwo = concreteObjectTwo; }
当您想要将接口绑定到正确的具体对象时,请使用“WhereTargetHas”方法:
Bind().To().WhereTargetHas(); Bind().To().WhereTargetHas();
更新:不使用属性的解决方案:
使用方法“When”:
Bind().To().When(r => r.Target.Name == "concreteObjectOne"); Bind().To().When(r => r.Target.Name == "concreteObjectTwo")
;
如果我可以被允许提供一些通用的,而不是针对Ninject的指导,我会建议您稍微重新考虑您的设计。 当前的构造函数是模糊的,因为它没有提供有关哪个IInterface实现的指导 – 我意识到这只是一个真实API的模型,而真正的API可能会为表单中的人类开发人员提供更多帮助对于恰当命名的参数,像DI Container这样的机器无法推断出正确的用法。
许多DI容器提供了一些解决这种模糊性的方法,例如通过提供可用于将名称(元数据)与每个依赖关联的属性。 AFAIR,Ninject有Inject
属性……
但是,请考虑几种替代方案:
第一种方法是将两个类似的接口实例封装在参数对象中 ,如下所示:
public interface IParameterObject { IInterface ObjectOne { get; } IInterface ObjectTwo { get; } }
您现在可以更改构造函数以获取IParameterObject的实例,而不是两个接口实例本身。
public Something(IParameterObject po) { this.concreteObjectOne = po.ObjectOne; this.concreteObjectTwo = po.ObjectTwo; }
这意味着您可以将IParameterObject的配置推送到Composition Root 。
思考的另一个替代方案是将两个实例作为一个特殊情况考虑是否有意义,这种情况只需要一个更通用的设计,它可以使用任意数量的实例。 这可能并非总是如此,但如果是,您可以将构造函数更改为:
public Something(IEnumerable objects)
我个人更喜欢上述任何建议,而不是任何使用特定Ninjectfunction的建议,因为它迫使我一般地使API更加明确,因此更具可读性和可维护性。