在这个问题中: Examples of IoC Containers
有一个答案警告构造函数中抛出的异常很难调试/处理,因为IoC会吃掉它们。随后发表评论说不再如此。
.Net IoC今天如何缓解这个缺陷,还是有一些仍然在这里受到影响?
我对至少2个组织使用的任何.Net IoC感兴趣(基本上不仅仅是作者),但是如果你需要一个列表:Windsor,StructureMap,Autofac,Ninject。
答案 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方法的调用都试图生成一个水合的,构造函数注入的对象,这将抛出所选构造函数中发生的任何异常。