首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Ninject中注入接口数组

在Ninject中注入接口数组
EN

Stack Overflow用户
提问于 2010-06-23 23:12:09
回答 4查看 6.7K关注 0票数 15

考虑下面的代码。

代码语言:javascript
复制
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>();
    }
}

当我尝试运行这个程序时,我得到了以下异常。

激活IFoo时出现

错误

没有匹配的绑定可用,并且类型不是可自绑定的。

激活路径:

2)将依赖项IFoo注入类型为Bar的构造函数的参数foos中

1)请求条形图

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

耽误您时间,实在对不起。

编辑:

我的应用程序导入由第三方组件创建的数据。导入过程应用不同类型的过滤器(例如,不同过滤器接口的实现)。过滤规则经常改变,但太复杂了,不能用纯配置(和主过滤器)来完成。

我想让添加/编辑过滤器变得尽可能简单。我拥有的是一个程序集,所有的过滤器实现都位于其中。我尝试将每个filter接口绑定到以下方法(它提供了该filter类型的每个实现的一个实例)。基本上,当我添加/删除过滤器类时,我希望避免更改我的Ninject模块。

代码语言:javascript
复制
    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>();
    }

就绕过容器依赖注入机制而言,我感到有点内疚。这是一种糟糕的做法吗?做这样的事情有没有一种普遍的做法?

解决方案:

我按照bsnote的建议使用了包装器类。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-06-24 20:00:40

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

Ninject (和其他DI /插件框架)有两个截然不同的工具:

绑定到允许获取一组服务that one then programmatically picks one of or aggregates across in some way的服务(Get)

  • A工具的单个明确实现的概念

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

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

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

它也可能对你解释你的真实情况很有用--为什么会有一个裸数组?当然,在这一切的背后肯定有一个项目构造的集合需要封装--这个问题肯定不会出现太多?

编辑:在扩展中有一组扫描示例,我想它们会攻击你想要做的很多东西(在像StructureMap这样的东西中,这类东西是更集成的,这显然是有优缺点的)。

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

无论哪种方式,当你有了多个注册时,你可以很高兴地“请求”一个T[]IEnumerable<T>并获得完整的集合。如果你想显式地实现这一点(例如,服务定位器和它所暗示的一切--就像你正在做的那样),你可以使用GetAll对它们进行批处理,这样你就不会进行隐含在你所做的方式中的循环了。

不确定是你做了这个连接还是我漏掉了什么。无论哪种方式,我希望它已经教会了你在问题中加入一些代码> 1000个单词:P

票数 7
EN

Stack Overflow用户

发布于 2012-11-15 00:57:12

Ninject支持多重注入,这将解决你的问题。https://github.com/ninject/ninject/wiki/Multi-injection

代码语言:javascript
复制
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..
    }
}
票数 11
EN

Stack Overflow用户

发布于 2010-06-24 15:29:58

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3102940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档