【问题标题】:Is there a way to propagate multiple injection?有没有办法传播多次注入?
【发布时间】:2016-10-15 17:26:35
【问题描述】:

我正在尝试让 Ninject 解析依赖关系树,该依赖关系树需要它根据依赖项的绑定数量来创建多个对象。

例如,假设我有这个类型系统:

public class A : IA
{
    public A(IB[] bs) { /* ... */ }
}

public class B : IB
{
    public B(IC c) { /* ... */ }
}

public class C1 : IC
{
    public C1() { /* ... */ }
}

public class C2 : IC
{
    public C2() { /* ... */ }
}

public interface IA { }
public interface IB { }
public interface IC { }

我可以配置 Ninject 来做这样的事情吗?

var a = new A(new IB[]
{
    new B(new C1()),
    new B(new C2())
});

我不想创建采用多种 IC 类型的 IB 实现,因为 IB 在逻辑上与使用单一 IC 类型相关联。处理更高级别的多个 IB 实例要容易得多。

我希望这样做会起作用:

var kernel = new StandardKernel();
kernel.Bind<IC>().To<C1>();
kernel.Bind<IC>().To<C2>();
kernel.Bind<IB>().To<B>();
kernel.Bind<IA>().To<A>();

var a = kernel.Get<IA>();

但它会抛出异常:

Error activating IC
More than one matching bindings are available.
Matching bindings:
  1) binding from IC to C1
  2) binding from IC to C2
Activation path:
  3) Injection of dependency IC into parameter c of constructor of type B
  2) Injection of dependency IB into parameter bs of constructor of type A
  1) Request for IA

【问题讨论】:

  • Ninject 可以做到,只要你没有循环依赖。
  • IMO,您已经越过了Pure DI 成为比使用 DI 容器更好的选择的界限。您基本上是在创建一个“复杂对象图”。更多详情请看我的文章:criticalsoftwareblog.com/index.php/2015/08/23/…
  • 先输出C1,然后输出C2 的工厂就可以了。

标签: c# ninject


【解决方案1】:

一种可能性是为IB + IC 的所有组合创建多个绑定:

var kernel = new StandardKernel();
kernel.Bind<IB>().To<B>()
    .WithParameter(
        new TypeMatchingConstructorArgument(
            typeof(IC), 
            (ctx, target) => ctx.Kernel.Get<C1>()));
kernel.Bind<IB>().To<B>()
    .WithParameter(
        new TypeMatchingConstructorArgument(
            typeof(IC),
            (ctx, target) => ctx.Kernel.Get<C2>()));
kernel.Bind<IA>().To<A>();

var a = kernel.Get<IA>();

【讨论】:

    猜你喜欢
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多