使用 Unity IOC 时发生 StackoverflowException

StackoverflowException when using Unity IOC

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

是否有任何方法可以追踪 unity 试图解决的问题并以某种方式找出正在发生的事情?

我有一个工作示例,我知道它可以使用 'design'。

我知道这不是一个理想的设计,我计划在生产线上引入一个演示器,但现在这应该可行,但我不知道为什么不行

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

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

public class Service2(IService1, IService5):IService2

这会导致异常吗?

EDIT2:是的,我刚刚使用第一次编辑中列出的循环引用创建了一个快速应用程序,但我收到了 WhosebugException - 显然是不允许的。

当你在 VS 中捕获异常时,进入它并遵循 InnerException。 Unity 应该打印所有已注册的类型,您可以看到缺少的类型。

另请查看堆栈跟踪。通常 Whosebug 当你有这样的循环依赖时出现:

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

A 取决于 B,反之亦然。 Unity 将尝试在 Actor 中注入一个 B 实例,但是 B 实例需要一个 A 实例,而这又需要一个 B ]等等。

这个例子很简单,但在实际工作中循环更难发现,因为不同库之间可能存在更复杂的依赖关系图,例如 A -> B - > C -> D -> A(其中“->”表示 "depends on")。

编辑 是的,如果您正在解析 IService1IService1 本身尚未注册,那么交叉引用服务可能会导致您出现 Whosebug 异常;

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

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

  2. 实际应用逻辑开始;现在你可以解决任何问题了。

解决方案 2

使用空 ctors 并在 Service class 内进行解析。可以使用RegisterType方法指定必须调用空的ctor

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

这里有更多关于 circular references with dependency injection using Unity.

的详细信息

解决方案 3

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