【问题标题】:Bind multiple interfaces to the same implementation将多个接口绑定到同一个实现
【发布时间】:2019-05-16 18:26:42
【问题描述】:

我对此问题有一个后续问题:Is it possible to bind different interfaces to the same instance of a class implementing all of them?

我有一个场景,其中一个接口需要通过“命名”扩展提供的名称来解析,而另一个不需要解析名称。

例如

public interface IMachine { }
public interface IDrillMachine : IMachine { }

public class Drill: IDrillMachine { }
public class ScrewDriver: IMachine { }

Ninject 绑定

Bind<IMachine, IDrillMachine>().To<Drill>().Named("Drill");
Bind<IMachine>.To<ScrewDriver>().Named("ScrewDriver");

注入

public class MachineConsumer
{
    public MachineConsumer([Named("Drill")]IMachine drillMachine)
    { }
}

public class DrillConsumer
{
    public DrillConsumer(IDrillMachine drillMachine)
    { }
}

我的代码不能正常工作,所以无法测试。但是我认为在解析IDrillMachine的时候会出现混乱,不是吗?

【问题讨论】:

  • 不确定这是否是问题所在,但在查看链接问题的已接受答案后,您似乎在 Ninject 绑定中错过了对 .InSingletonScope() 的调用。
  • 添加.InSingletonScope() 的唯一区别是我将获得一个实例,而不是DrillMachine 的新实例。最初的问题仍然存在,即 Ninject 是否能够解决 IDrillMachine 并给我一个 DrillMachine 的实例?

标签: c# ninject


【解决方案1】:

这不起作用,因为DrillConsumer 构造函数缺少[Named("Drill")] 名称规范,但IDrillMachine 的绑定需要它。 您的方案可以通过Drill 的两个单独绑定来解决:

Bind<IMachine>().To<Drill>().Named("Drill");
Bind<IDrillMachine>().To<Drill>();

如果Drill 需要成为像单例这样的作用域对象,那就有点复杂了。将InSingletonScope() 添加到两个绑定将产生两个实例,一个用于IMachine("Drill") 的单例,一个用于IDrillMachine

要解决此问题,您可以添加一个间接级别:

Bind<IMachine>().ToMethod(ctx => ctx.Kernel.Get<Drill>()).Named("Drill");
Bind<IDrillMachine>().ToMethod(ctx => ctx.Kernel.Get<Drill>());
Bind<Drill>().ToSelf().InSingletonScope();

【讨论】:

  • 感谢您的回答。令我惊讶的是,DrillConsumer 被实例化得很好,并且不需要 [Named("Drill")] 规范。
最近更新 更多