我在Winforms应用程序中使用unity通过将依赖项注入到表单的构造函数中(我知道这不是最佳实践)但它确实有效但我在尝试加载mdi表单时遇到stackoverflowexception。
有没有办法追踪团结试图解决的问题,并以某种方式找出正在发生的事情?
我有一个工作示例,我知道使用这种'设计'。
我知道这不是一个理想的设计,我计划在线上引入一个Presenter但是现在这应该有效,我不知道它为什么不是
编辑: 我知道我有相互引用的服务,例如
public class Service1(IService2, IService3, IService4):IService1
public class Service2(IService1, IService5):IService2
会导致异常吗?
EDIT2:是的我刚刚创建了一个带有这个循环引用的快速应用程序,如我的第一个编辑中所列,我得到了一个StackOverflowException - 显然是不允许的。
答案 0 :(得分:3)
当您在VS中捕获异常时,请进入其中并按照InnerException
进行操作。 Unity应该打印所有已注册的类型,你可以看到哪些类型丢失。
另请参阅堆栈跟踪。通常StackOverflow
出现在你有这样的循环依赖时:
class A { A(B b) { ... } }
class B { B(A a) { ... } }
A
取决于B
,反之亦然。 Unity将尝试注入ctor
A
个B
实例,但B
实例需要A
个实例,同样需要B
个实例等等。
这个例子是一个微不足道的例子,但在实际工作中,循环性更难以发现,因为在不同的库之间可能存在更复杂的依赖图,例如A
- > B
- > C
- > D
- > A
(其中“ - >”表示“取决于”)。
修改强>
是的,如果您正在解析IService1
,IService1
本身尚未注册,那么交叉引用服务可能会导致您发生堆栈溢出异常;
解决方案1 如果类型注册和解决分两步进行(粗略的想法),您可以绕过此问题:
注册同时注册IService1
及其类型和IService2
及其类型。此步骤仅执行注册代码,不处理任何其他事情(UI,启动逻辑,统一解析,http通信等)。
实际应用程序逻辑启动;现在你可以解决任何问题。
解决方案2
使用空ctors
并在Service
课程中进行解析。您可以使用RegisterType
方法指定必须调用空ctor
:
container.RegisterType<IServiceProvider, ServiceContainer>(new InjectionConstructor());
以下是有关circular references with dependency injection using Unity.
的详细信息解决方案3
使用Lazy<IService>
进行解析。使用此实际解析将根据需要进行,更具体的是第一次调用第一次Lazy.Value
属性时。