在Ninject中注入接口数组

请考虑以下代码。

public interface IFoo { } public class Bar { public Bar(IFoo[] foos) { } } public class MyModule : NinjectModule { public override void Load() { Bind().ToConstant(new IFoo[0]); // ToConstant() is just an example } } public class Program { private static void Main(string[] args) { var kernel = new StandardKernel(new MyModule()); var bar = kernel.Get(); } } 

当我尝试运行该程序时,我得到以下exception。

激活IFoo时出错
没有匹配的绑定可用,并且该类型不可自绑定。
激活路径:
2)将依赖关系IFoo注入到Bar类型构造函数的参数foos中
1)要求酒吧

如何在Ninject中注入/绑定到数组?

谢谢你的时间。

编辑:
我的应用程序导入由第三方组件创建的数据。 导入过程应用不同类型的filter(例如,不同filter接口的实现)。 过滤规则经常发生变化,但过于复杂,无法使用纯配置(和主filter)。

我想尽可能简单地添加/编辑filter。 我所拥有的是一个所有filter实现所在的程序集。我尝试将每个filter接口绑定到以下方法(它提供该filter类型的每个实现的实例)。 基本上我想避免在添加/删除filter类时更改我的Ninject模块。

  private IEnumerable GetInterfaceImplementations(IContext context) { return GetType().Assembly.GetTypes() .Where(t => typeof (TInterface).IsAssignableFrom(t) && IsConcreteClass(t)) .Select(t => Kernel.Get(t)).Cast(); } 

在绕过容器DI机制方面我感到有点内疚。 这是一个不好的做法吗? 做这样的事情有共同的做法吗?

解析度:
我使用包装类作为bsnote建议。

这很大程度上是对@bsnote的回答(我已经+ 1d)的重述,这可能有助于理解它为什么以这种方式工作。

Ninject(和其他DI / addin框架)有两个不同的设施:

  1. 绑定到单个明确的服务实现的概念( Get
  2. 允许一个人获得一组服务的工具[然后以编程方式选择其中一个或以某种方式聚合](Ninject中的GetAll / ResolveAll

您的示例代码恰好使用与上面的2.相关联的语法。 (例如,在MEF中,通常使用[ImportMany]注释来明确这一点)

我需要查看示例(查看源代码 – 它非常简短,干净且易于遵循)以找到解决方法。

但是,正如@bsnote所说,重构您的需求的一种方法是将数组包装在容器中,或者拥有一个您要求它的对象(即工厂方法或存储库类型构造)

你可以解释一下你的真实案例是什么 – 为什么有一个裸arrays? 肯定有一个项目构建的集合乞求封装所有这些 – 这个问题当然不会出现太多?

编辑:在扩展中有一组扫描示例,我想这会攻击你正在尝试做的很多事情(在结构图这样的东西中,这种东西更加集成,显然有利有弊)。

根据您是否尝试实现约定优于配置,您可能需要考虑在每种类型的插件上粘贴标记接口。 然后你可以明确Bind每一个。 或者,对于CoC,您可以使ModuleLoad()例程循环遍历您在编辑中生成的一组实现(即,许多单独的Get )。

无论哪种方式,当你有多个注册时,你可以愉快地’请求’ T[]IEnumerable并获得全套。 如果你想明确地实现这一点(即,服务定位器和它所暗示的一切 – 就像你正在做的那样,你可以使用GetAll来批处理它们,这样你就不会像你所做的那样进行隐式循环。

不确定你是否已建立此连接或我是否遗漏了某些内容。 无论哪种方式,我希望它教你将一些代码粘贴到问题中,因为它说的是> 1000个单词:P

Ninject支持多次注射,可以解决您的问题。 https://github.com/ninject/ninject/wiki/Multi-injection

 public interface IFoo { } public class FooA : IFoo {} public class FooB : IFoo {} public class Bar { //array injected will contain [ FooA, FooB ] public Bar(IFoo[] foos) { } } public class MyModule : NinjectModule { public override void Load() { Bind().To(); Bind().To(); //etc.. } } 

对我来说这也是一个问题。 Ninject注入数组的每个项而不是数组本身,因此您应该为数组项的类型定义映射。 实际上,不可能将数组映射为具有当前版本的Ninject的类型。 解决方案是在数组周围创建一个包装器。 例如,如果它适合您,可以使用惰性类。 或者您可以创建自己的包装器。