使用 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 将尝试在 A
的 ctor
中注入一个 B
实例,但是 B
实例需要一个 A
实例,而这又需要一个 B
]等等。
这个例子很简单,但在实际工作中循环更难发现,因为不同库之间可能存在更复杂的依赖关系图,例如 A
-> B
- > C
-> D
-> A
(其中“->”表示 "depends on")。
编辑
是的,如果您正在解析 IService1
,IService1
本身尚未注册,那么交叉引用服务可能会导致您出现 Whosebug 异常;
解决方案 1
如果类型注册和解析分两步进行,则可以绕过此问题(粗略的想法):
注册同时注册IService1
及其类型和IService2
及其类型。这一步只做注册代码,不处理任何其他事情(UI、启动逻辑、统一解析、http 通信等)。
实际应用逻辑开始;现在你可以解决任何问题了。
解决方案 2
使用空 ctors
并在 Service
class 内进行解析。可以使用RegisterType
方法指定必须调用空的ctor
:
container.RegisterType<IServiceProvider, ServiceContainer>(new InjectionConstructor());
这里有更多关于 circular references with dependency injection using Unity.
的详细信息
解决方案 3
使用Lazy<IService>
解析。使用这个实际解析将按需进行,更具体的是第一次调用 Lazy.Value
属性 时。
我通过将依赖项注入表单的构造函数来在 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 将尝试在 A
的 ctor
中注入一个 B
实例,但是 B
实例需要一个 A
实例,而这又需要一个 B
]等等。
这个例子很简单,但在实际工作中循环更难发现,因为不同库之间可能存在更复杂的依赖关系图,例如 A
-> B
- > C
-> D
-> A
(其中“->”表示 "depends on")。
编辑
是的,如果您正在解析 IService1
,IService1
本身尚未注册,那么交叉引用服务可能会导致您出现 Whosebug 异常;
解决方案 1 如果类型注册和解析分两步进行,则可以绕过此问题(粗略的想法):
注册同时注册
IService1
及其类型和IService2
及其类型。这一步只做注册代码,不处理任何其他事情(UI、启动逻辑、统一解析、http 通信等)。实际应用逻辑开始;现在你可以解决任何问题了。
解决方案 2
使用空 ctors
并在 Service
class 内进行解析。可以使用RegisterType
方法指定必须调用空的ctor
:
container.RegisterType<IServiceProvider, ServiceContainer>(new InjectionConstructor());
这里有更多关于 circular references with dependency injection using Unity.
的详细信息解决方案 3
使用Lazy<IService>
解析。使用这个实际解析将按需进行,更具体的是第一次调用 Lazy.Value
属性 时。