.Net IoC如何处理构造函数中的异常?

时间:2012-09-10 19:37:34

标签: c# .net inversion-of-control ioc-container

在这个问题中: Examples of IoC Containers

有一个答案警告构造函数中抛出的异常很难调试/处理,因为IoC会吃掉它们。随后发表评论说不再如此。

.Net IoC今天如何缓解这个缺陷,还是有一些仍然在这里受到影响?

我对至少2个组织使用的任何.Net IoC感兴趣(基本上不仅仅是作者),但是如果你需要一个列表:Windsor,StructureMap,Autofac,Ninject。

3 个答案:

答案 0 :(得分:3)

显然这取决于您使用的IoC容器。根据我的经验,很少是“吞下”的例外情况,在解决时会报告。如果你遵循一个常见的最佳做法,即除了接受和验证构造函数中的依赖关系之外什么都不做,那么你应该没问题。

以下是团结的例子:

void Main()
{
    IUnityContainer container = new UnityContainer();
    container.RegisterType<IAnimal, Dog>();

    // Exception thrown on this line
    var x = container.Resolve<IAnimal>();
}

public interface IAnimal
{
}

public class Dog : IAnimal
{
    public Dog()
    {
        throw new Exception();
    }
}

报告此事(我认为这是非常有用的信息):

ResolutionFailedException: Resolution of the dependency failed, type = "UserQuery+IAnimal", name = "(none)".
Exception occurred while: Calling constructor UserQuery+Dog().
Exception is: Exception - Exception of type 'System.Exception' was thrown.
-----------------------------------------------
At the time of the exception, the container was:

Resolving UserQuery+Dog,(none) (mapped from UserQuery+IAnimal, (none))
Calling constructor UserQuery+Dog()

答案 1 :(得分:1)

我知道,如果构造函数中出现异常,StructureMap会冒出异常,但这条规则可能会有一些奇怪的细微差别。例如,如果您正在使用SingletonPattern调度程序并且您指定的Singleton在程序执行的早期安静地崩溃,那么StructureMap将很乐意将崩溃的实例输入到请求单例类型的任何内容中。那时很难说会发生什么,这一切都取决于你的程序如何处理对崩溃实例的访问。

但是,作为一个例子,它会向你抛出,如果你试图用无效或类型不匹配的参数调用一个对象的构造函数,它会在调用调用时抛出一个描述性错误。设置通常可以正常工作,但您可以使用基本单元测试(NUnit)提前测试:

[Test]  
public void Assert_registry_is_valid()  
{  
    ObjectFactory.AssertConfigurationIsValid();  
}  

我当然从未遇到过使用StructureMap吞咽错误的问题。通常很容易从中获取有用的信息和完整的堆栈跟踪。

答案 2 :(得分:1)

我知道Autofac将“包装”在尝试热切解决依赖关系时抛出的异常。 AutofacException的InnerException将是构造函数抛出到容器的异常。因此,您通常通过捕获AutofacExceptions并钻取InnerExceptions来处理解决方案异常。

大多数IoC都有类似“TryResolve”的方法,它们优雅地返回true或false布尔值,输出参数在分辨率成功时初始化。这些方法是“吃掉”异常的方法,因此如果异常对您有用,请不要使用这些方法。几乎所有对基本GetInstance或Resolve方法的调用都试图生成一个水合的,构造函数注入的对象,这将抛出所选构造函数中发生的任何异常。