NInject通用通用和特定绑定

时间:2018-07-16 08:03:24

标签: c# dependency-injection ninject

我有一个标准的通用类,而对于某些类型参数来说,只有很少的类可以使用特定的逻辑对其进行扩展。特定的类可能在另一个程序集中,因此存在不同的模块。我猜想除了实现通用泛型注册外,还注册实现的泛型类型,它可以工作,但是我不知道为什么。 NInject如何以正确的方式解析viewer3,它需要最具体的注册吗?单身人士可能有任何问题吗?谢谢。

class Program
{
    static void Main(string[] args)
    {
        IKernel kernel = new StandardKernel(new StandardModule(), new BoolModule());

        var viewer1 = kernel.Get<IViewer<string>>();
        var viewer2 = kernel.Get<IViewer<int>>();
        var viewer3 = kernel.Get<IViewer<bool>>();

        viewer1.Show("abc");
        viewer2.Show(123);
        viewer3.Show(true);
    }
}

interface IViewer<T>
{
    void Show(T value);
}

class StandardViewer<T> : IViewer<T>
{
    public void Show(T value)
    {
        Console.WriteLine(value);
    }
}

class BoolViewer : IViewer<bool>
{
    public void Show(bool value)
    {
        Console.WriteLine(value ? "yes!" : "no :(");
    }
}

class StandardModule : NinjectModule
{
    public override void Load()
    {
        Bind(typeof(IViewer<>)).To(typeof(StandardViewer<>)).InSingletonScope();
    }
}

class BoolModule : NinjectModule
{
    public override void Load()
    {
        Bind<IViewer<bool>>().To<BoolViewer>().InSingletonScope();
    }
}

及相关问题。如果我想向BoolViewer添加某种方法,那么在解析时如何仅通过强制转换使用它?

var viewer3 = kernel.Get<IViewer<bool>>();
((BoolViewer)viewer3).SomeMethod();

1 个答案:

答案 0 :(得分:1)

通常,如果您为同一类型添加多个绑定,则将使用它们来注入一个数组(根据multi-injection documentation),因此不会,Ninject不会选择最相关的绑定。

您可能会将其与构造函数混淆,Ninject将在其中应用constructor injection的规则:

  
      
  • 如果构造函数具有[Inject]属性,则会使用该属性(但如果将该属性应用于多个属性,则Ninject会抛出一个
      检测到运行时出现NotSupportedException)。

  •   
  • 如果没有构造函数具有[Inject]属性,则Ninject将选择Ninject理解如何具有最多参数的那个
      解决。

  •   
  • 如果未定义任何构造函数,则Ninject将选择默认的无参数构造函数(假设有一个)。

  •   

但是,您所拥有的是通用绑定。如果您查看release notes for Ninject 3.0.0,将会看到以下功能:

  

添加:对于以下情况,封闭的泛型可以覆盖开放的泛型绑定:   特定类型。

因此,您为bool使用了封闭的泛型进行绑定,这将实例化BoolViewer。对IViewer<>的所有其他请求将使用开放的通用绑定。