使用Unity IOC时出现StackoverflowException

时间:2015-10-13 10:52:43

标签: inversion-of-control unity-container

我在Winforms应用程序中使用unity通过将依赖项注入到表单的构造函数中(我知道这不是最佳实践)但它确实有效但我在尝试加载mdi表单时遇到stackoverflowexception。

有没有办法追踪团结试图解决的问题,并以某种方式找出正在发生的事情?

我有一个工作示例,我知道使用这种'设计'。

我知道这不是一个理想的设计,我计划在线上引入一个Presenter但是现在这应该有效,我不知道它为什么不是

编辑: 我知道我有相互引用的服务,例如

public class Service1(IService2, IService3, IService4):IService1

public class Service2(IService1, IService5):IService2

会导致异常吗?

EDIT2:是的我刚刚创建了一个带有这个循环引用的快速应用程序,如我的第一个编辑中所列,我得到了一个StackOverflowException - 显然是不允许的。

1 个答案:

答案 0 :(得分:3)

当您在VS中捕获异常时,请进入其中并按照InnerException进行操作。 Unity应该打印所有已注册的类型,你可以看到哪些类型丢失。

另请参阅堆栈跟踪。通常StackOverflow出现在你有这样的循环依赖时:

class A { A(B b) { ... } }
class B { B(A a) { ... } }

A取决于B,反之亦然。 Unity将尝试注入ctor AB实例,但B实例需要A个实例,同样需要B个实例等等。

这个例子是一个微不足道的例子,但在实际工作中,循环性更难以发现,因为在不同的库之间可能存在更复杂的依赖图,例如A - > B - > C - > D - > A(其中“ - >”表示“取决于”)。

修改 是的,如果您正在解析IService1IService1本身尚未注册,那么交叉引用服务可能会导致您发生堆栈溢出异常;

解决方案1 ​​ 如果类型注册和解决分两步进行(粗略的想法),您可以绕过此问题:

  1. 注册同时注册IService1及其类型和IService2及其类型。此步骤仅执行注册代码,不处理任何其他事情(UI,启动逻辑,统一解析,http通信等)。

  2. 实际应用程序逻辑启动;现在你可以解决任何问题。

  3. 解决方案2

    使用空ctors并在Service课程中进行解析。您可以使用RegisterType方法指定必须调用空ctor

    container.RegisterType<IServiceProvider, ServiceContainer>(new InjectionConstructor());
    

    以下是有关circular references with dependency injection using Unity.

    的详细信息

    解决方案3

    使用Lazy<IService>进行解析。使用此实际解析将根据需要进行,更具体的是第一次调用第一次Lazy.Value属性时。