Design patterns 处理IOC中的循环依赖
我正在尝试使用IOC容器在我的应用程序中创建初始对象图 我有一张主表格。此表单依赖于一个MenuStrip,该MenuStrip依赖于多个MenuStripItem。一些菜单项依赖于主窗体 目前,我为构造函数注入设置了所有依赖项。显然,解析MainForm现在会导致堆栈溢出,因为MainForm的MenuStripItem依赖项试图解析MainForm,等等Design patterns 处理IOC中的循环依赖,design-patterns,inversion-of-control,Design Patterns,Inversion Of Control,我正在尝试使用IOC容器在我的应用程序中创建初始对象图 我有一张主表格。此表单依赖于一个MenuStrip,该MenuStrip依赖于多个MenuStripItem。一些菜单项依赖于主窗体 目前,我为构造函数注入设置了所有依赖项。显然,解析MainForm现在会导致堆栈溢出,因为MainForm的MenuStripItem依赖项试图解析MainForm,等等 解决此循环依赖的最佳方法是什么?无论您是否使用IoC,循环依赖都是设计糟糕的标志。我建议你重新设计以避免它。添加辅助对象可能是一种解决方案
解决此循环依赖的最佳方法是什么?无论您是否使用IoC,循环依赖都是设计糟糕的标志。我建议你重新设计以避免它。添加辅助对象可能是一种解决方案
比如说,,使MenuStripItem仅依赖于主窗体的一个必要部分,而不是整体。创建一个控制器类,该类提供主窗体和MenuStripItem都需要的数据和逻辑,以避免循环引用。之后可以使用setter注入一些依赖项构造。我不知道创建助手类或控制器如何解决循环依赖性问题 我会提供更多的细节。 菜单项依赖于MainForm,因为它们可以设置MainForm的内容。按照上面的建议,假设我为主表单内容IFormContent创建了一个单独的接口。 MenuStripItem可以依赖于IFormContent。 但IFormContent的实现将再次依赖于MainForm,从而产生循环依赖
也许我应该在某个地方使用setter注入,而不是构造函数注入?如何创建MenuStrip和menustripitem
当我使用IOC时,服务和IOC容器为服务提供的依赖项之间总是存在1对1的关系。如果一个服务需要多个项目,那么它将与创建多个项目的单个factory对象建立1对1关系。此factory方法可以参数化,以允许创建的项引用回其容器。我同意kgiannakakis的观点:
循环依赖关系是 糟糕的设计,无论您是否使用 国际奥委会与否。我建议你做一个调查 重新设计以避免它。添加助手 对象可能是一种解决方案 要找出应将哪些方法提取到helper类中,此过程可能有助于: 假设您有一个类a和一个类B,它们相互引用并创建循环依赖关系。 要找出要提取到外部帮助程序项目中的方法,请列出类A使用的类A中的所有方法,以及类A使用的类B中的所有方法。两个列表中较短的是隐藏的帮助程序类C
受Miško Hevery的启发您需要创建一个经销商类(或接口),其中包含您正在使用的两个类的引用。您应该使用此经销商类(或接口),而不是您以前尝试使用的每个参考类 解释解决方案:
考虑以下3个类:
public Class A {
public Method CommonMethod(){
//Some implementation...
}
Method C(){
//CommonMethod form class B are using here
B obj = new B();
B.CommonMethod();
}
}
public Class B {
public Method CommonMethod(){
//Some implementation...
}
Method D(){
//CommonMethod form class A are using here
A obj = new A();
A.CommonMethod();
}
}
public Class DealerClass {
private readonly A _inctanceA;
private readonly B _inctanceB;
//Cunstructor method of the class
DealerClass(A inctanceA, B inctanceB){
_inctanceA = inctanceA;
_inctanceB = inctanceB;
}
//Using CommonMethod of class A
public UsingCommonMethodA(){
_inctanceA.CommonMethod();
}
//Using CommonMethod of class B
public UsingCommonMethodB(){
_inctanceB.CommonMethod();
}
}
因此,根据这个解决方案,您应该在
DealerClass
中使用其他类的方法,这些类之间具有循环依赖关系。我很好奇,在涉及IOC容器之前,您是如何处理循环引用的。。。您是否有一个单元测试来传递窗体的所有依赖项?在使用IOC之前,我的主窗体将使用单例进行全局访问。有关循环依赖项的一些引用:您有一个具有一个属性的控制器类:Content。MenuStripItem在控制器上设置Content属性,MainForm读取该属性。因此,这两个类引用控制器,但控制器对这两个GUI类一无所知。因此,没有循环参考。它似乎更详细。