当最大的构造函数有无法解析的依赖时,如何强制Ninject异常?

本文关键字:何强制 Ninject 异常 依赖 构造函数 | 更新日期: 2023-09-27 17:55:06

根据Ninject的文档:

主要的DI模式是构造函数注入。当激活类型的实例时,Ninject将按顺序应用以下规则选择要使用的类型的构造函数之一:-

  1. 如果一个构造函数有一个[Inject]属性,它就会被使用(但是如果你把这个属性应用到多个构造函数上,Ninject会在运行时检测到时抛出NotSupportedException)。

  2. 如果没有构造函数有[Inject]属性,Ninject将选择参数最多且Ninject知道如何解析的构造函数。

  3. 如果没有定义构造函数,Ninject将选择默认的无参数构造函数(假设有一个)。

如果你快速浏览这个列表,似乎在#2中有一个很难忽略的问题。问题在that Ninject understands how to resolve .

考虑以下场景:

// Defined in MyController.cs
public void MyController(IMyDependency depencency) { }
// Defined in MyController.generated.cs for T4
public void MyController() { }

如果Ninject没有任何类型绑定到IMyDependency,然后调用kernel.Resolve<MyController>(),它将异常,而是通过,使用无参数构造函数代替。

然而,这绝对是不是想要的行为,因为我想要立即得到解析失败的通知,并且默认的Ninject功能也使得在编码测试中测试IOC解析是不可能的。

是否有任何方法有Ninject异常,如果解析失败的构造函数与最多的参数,而不是回退到其他构造函数,如果可能的话?

当最大的构造函数有无法解析的依赖时,如何强制Ninject异常?

实现您自己的IConstructorScorer,可能是通过子类化默认的StandardConstructorScorer并给您不喜欢的构造函数低分数…

Ninject通过IConstructorScorer接口运行每个构造函数,以确定应该使用哪个构造函数来实例化类

如何做到这一点的详细信息在github的文档。

在您的例子中,它可能看起来像这样:

public class MyScorer : StandardConstructorScorer
{
    public override int Score(IContext context, ConstructorInjectionDirective directive)
    {
        //has more than one constructor
        //and the constructor being considered is parameterless
        if (directive.Constructor.GetType().GetConstructors().Count() > 1 
            && !directive.Targets.Any())
        {
            //give it a low score
            return Int32.MinValue;
        }
        return base.Score(context, directive);
    }
}