Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 处理IOC中的循环依赖_Design Patterns_Inversion Of Control - Fatal编程技术网

Design patterns 处理IOC中的循环依赖

Design patterns 处理IOC中的循环依赖,design-patterns,inversion-of-control,Design Patterns,Inversion Of Control,我正在尝试使用IOC容器在我的应用程序中创建初始对象图 我有一张主表格。此表单依赖于一个MenuStrip,该MenuStrip依赖于多个MenuStripItem。一些菜单项依赖于主窗体 目前,我为构造函数注入设置了所有依赖项。显然,解析MainForm现在会导致堆栈溢出,因为MainForm的MenuStripItem依赖项试图解析MainForm,等等 解决此循环依赖的最佳方法是什么?无论您是否使用IoC,循环依赖都是设计糟糕的标志。我建议你重新设计以避免它。添加辅助对象可能是一种解决方案

我正在尝试使用IOC容器在我的应用程序中创建初始对象图

我有一张主表格。此表单依赖于一个MenuStrip,该MenuStrip依赖于多个MenuStripItem。一些菜单项依赖于主窗体

目前,我为构造函数注入设置了所有依赖项。显然,解析MainForm现在会导致堆栈溢出,因为MainForm的MenuStripItem依赖项试图解析MainForm,等等


解决此循环依赖的最佳方法是什么?

无论您是否使用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类一无所知。因此,没有循环参考。它似乎更详细。