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

时间:2015-06-09 22:46:27

标签: c# ninject

根据Ninject的文件:

  

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

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

  2.   
  3. 如果没有构造函数具有[Inject]属性,Ninject将选择Ninject了解如何解析的参数最多的那个。

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

  6.   

如果你快速浏览这个清单,似乎很难错过#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>(),它将异常,而是使用无参数构造函数传递。

然而,这绝对是 NOT 期望的行为,因为我希望立即得到解决方案失败的通知,并且默认的Ninject功能也使得无法在编码测试中测试IOC分辨率。

如果具有最多参数的构造函数上的解析失败并且如果可能的话不会回退到其他构造函数,是否有任何方法可以获得Ninject异常?

1 个答案:

答案 0 :(得分:2)

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

  

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

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