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

How can I force Ninject to exception when largest constructor has unresolvable dependencies?

根据 Ninject 的文档:

The primary DI pattern is Constructor Injection. When activating an instance of a type Ninject will choose one of the type’s constructors to use by applying the following rules in order:-

  1. 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).

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

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

#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 异常?

实现您自己的 IConstructorScorer,可能是通过继承默认 StandardConstructorScorer 并对您不喜欢其外观的构造函数给予低分...

Ninject runs each constructor through the IConstructorScorer interface to determine which constructor it should use to instantiate the class

有关如何执行此操作的详细信息,请参阅 documentation on 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);
    }
}