C# 由于依赖于自身,Factory对象导致stackoverflowexception

C# 由于依赖于自身,Factory对象导致stackoverflowexception,c#,factory-pattern,circular-dependency,C#,Factory Pattern,Circular Dependency,我有一个c#factory对象,它使用对象列表作为源,通过工厂方法创建对象 对象列表的创建方式如下: public WidgetFactory() { widgetLibrary = new List<WidgetModel>(); //Add all widgets widgetLibrary.Add(new ClientsWidget()); widgetLibrary.Add(new Installati

我有一个c#factory对象,它使用对象列表作为源,通过工厂方法创建对象

对象列表的创建方式如下:

public WidgetFactory()
    {
        widgetLibrary = new List<WidgetModel>();

        //Add all widgets
        widgetLibrary.Add(new ClientsWidget());
        widgetLibrary.Add(new InstallationsWidget());
        etc.
公共WidgetFactory() { widgetLibrary=新列表(); //添加所有小部件 Add(newclientswidget()); 添加(新安装swidget()); 等 我的应用程序的各个部分以不同的方式访问此列表,以获得它所需的对象类型

但我现在有一个要求,列表中的一个对象(即小部件)需要使用小部件工厂本身。显然,这会导致循环引用


如何更改设计以满足这一需求?

对于初学者,将小部件创建移出WidgetFactory的构造函数。这应该在初始化方法或CreateWidget(Type)方法中按需进行

要使工厂实例可用于小部件实例,可以执行以下几种操作之一:

  • 让WidgetFactory在创建小部件时通过“this”
  • 使用单例模式:添加静态属性WidgetFactory.Instance并初始化它一次;让所有WidgetFactory用户访问该属性,而不是创建新实例
  • 使用这种模式——这里很难提供简短的描述
  • 但我现在有一个要求,列表中的一个对象(即小部件)需要使用小部件工厂本身。显然,这会导致循环引用

    我如何改变我的设计以适应这种需要

    通常,对象不应依赖于创建它们的工厂进行构造,因为这正是导致此问题的原因。如果您可以将引用推入工厂,但在需要时才使用它,则可能会解决此问题

    如果您确实需要这样做,那么最好的方法可能是在工厂内惰性地实例化对象。您可以使用
    列表
    ,而不是让
    WidgetFactory
    在内部包含
    列表
    。这将允许单独的“小部件”仅在需要时进行评估,这意味着,当相关小部件尝试引用工厂时,它将被完全加载

    但我现在有一个要求,列表中的一个对象(即小部件)需要使用小部件工厂本身。显然,这会导致循环引用

    我如何改变我的设计以适应这种需要

    你的模型是错误的。一旦一辆汽车离开NUMMI工厂的装配线,它就不依赖工厂正常运转

    还有,我对你们工厂的设计提出了质疑。为什么你们要新建一个构造函数。它的用途是什么


    您可能应该告诉我们更多关于您的模型的信息,以及为什么您认为您需要它。很可能,如果做得好,您不需要。WidgetFactory的构造函数不应该调用它正在构建的东西的构造函数。相反,WidgetFactory应该有一个方法(
    BuildWidgets
    )这就完成了所有的工作


    然后其他对象可以利用工厂,而不会导致这一连串的活动重新开始。

    对不起,你只是抛出一些流行语,希望其中一个是正确的吗?@Jason ha!不,但我明白你为什么这么说。这两种方法都是解决OP问题的有效方法,但我想我的答案可以使用更多细节。我们根据这个类比,正在生产的对象是另一个汽车工厂。这个工厂正在为UI元素创建模型,但我现在需要创建一个映射到工厂的UI元素。这有意义吗?@Jon Eastwood:听起来这个工厂做得太多了(构建工厂和UI小部件?)。你应该把责任分开。我同意这一点,我认为这是问题的根源,但我不确定如何改变它。我需要一种方法来列举工厂可以创建的对象的可能类型,而不必为每个对象显式地编写生成方法。第一个想法奏效了,我只需要更加小心在这种情况下使用工厂。