NInject 通用通用和特定绑定

NInject generic common and specific bindings

我有一个标准的泛型 class 和一些 class 用于某些类型参数的使用特定逻辑扩展它的类型。特定的 classes 可能在另一个程序集中,因此有不同的模块。我猜想除了通用通用注册之外还要注册已实现的通用类型并且它有效,但我不知道为什么。 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();

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

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

的规则
  • If a constructor has an [Inject] attribute, it is used (but if you apply the attribute to more than one, Ninject will throw a
    NotSupportedException at runtime upon detection).

  • If no constructors have an [Inject] attribute, Ninject will select the one with the most parameters that Ninject understands how to
    resolve.

  • If no constructors are defined, Ninject will select the default parameterless constructor (assuming there is one).

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

Added: Open generic bindings can be overriden by closed generics for specific types.

因此,您有一个使用 bool 的封闭泛型的绑定,这将实例化您的 BoolViewerIViewer<> 的所有其他请求将使用开放通用绑定。