Jul*_*ner 14 .net c# arrays dependency-injection ninject
请考虑以下代码.
public interface IFoo { }
public class Bar
{
public Bar(IFoo[] foos) { }
}
public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IFoo[]>().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<Bar>();
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试运行该程序时,我得到以下异常.
激活IFoo时出错
没有匹配的绑定可用,并且该类型不可自我绑定.
激活路径:
2)将依赖关系IFoo注入到Bar
1 类型的构造函数的参数foo中.请求Bar
如何在Ninject中注入/绑定到数组?
谢谢你的时间.
编辑:
我的应用程序导入由第三方组件创建的数据.导入过程应用不同类型的过滤器(例如,不同过滤器接口的实现).过滤规则经常发生变化,但过于复杂,无法使用纯配置(和主过滤器).
我想尽可能简单地添加/编辑过滤器.我所拥有的是一个所有过滤器实现所在的程序集.我尝试将每个过滤器接口绑定到以下方法(它提供该过滤器类型的每个实现的实例).基本上我想避免在添加/删除过滤器类时更改我的Ninject模块.
private IEnumerable<TInterface> GetInterfaceImplementations<TInterface>(IContext context)
{
return GetType().Assembly.GetTypes()
.Where(t => typeof (TInterface).IsAssignableFrom(t) && IsConcreteClass(t))
.Select(t => Kernel.Get(t)).Cast<TInterface>();
}
Run Code Online (Sandbox Code Playgroud)
在绕过容器DI机制方面我感到有点内疚.这是一种不好的做法吗?做这样的事情有共同的做法吗?
解决方案:
我使用包装类作为bsnote建议.
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<IFoo>().To<FooA>();
Bind<IFoo>().To<FooB>();
//etc..
}
}
Run Code Online (Sandbox Code Playgroud)
这主要是对@bsnote的回答(我已经+ 1d)的重述,这可能有助于理解为什么它以这种方式工作.
Ninject(和其他DI/addin框架)有两个不同的设施:
Get
)GetAll
/ ResolveAll
在Ninject中)您的示例代码恰好使用与上面的2.相关联的语法.(例如,在MEF中,通常使用[ImportMany]
注释来明确这一点)
我需要查看示例(查看源代码 - 它非常简短,干净且易于遵循)以找到解决方法.
但是,正如@bsnote所说,重构您的需求的一种方法是将数组包装在容器中,或者拥有一个您要求它的对象(即工厂方法或存储库类型构造)
你可以解释一下你的真实案例是什么 - 为什么有一个裸阵列?当然有一个项目构建的集合乞求被封装在所有这一切 - 这个问题肯定不会出现太多?
编辑:扩展中有一组扫描示例,我想会攻击你要做的很多东西(在StructureMap这样的东西中,这种东西更集成,显然有利有弊).
根据您是否尝试实现约定优于配置,您可能需要考虑在每种类型的插件上粘贴标记接口.然后你可以明确地指出Bind
每一个.或者,为COC,可以使Module
的Load()
在集实现你生成(即,大量的个人的日常循环Get
在你的编辑S).
无论哪种方式,当你有多个注册时,你可以愉快地'请求' T[]
或者IEnumerable<T>
获得全套.如果你想明确地实现这一点(即,服务定位器和它所暗示的一切 - 就像你正在做的那样,你可以用它GetAll
来批处理它们,这样你就不会像你做的那样进行隐式循环.
不确定你是否已建立此连接或我是否遗漏了某些内容.无论哪种方式,我希望它教会你将一些代码粘贴到问题中,因为它说的是> 1000个单词:P
归档时间: |
|
查看次数: |
6012 次 |
最近记录: |