2011-06-24 23 views
2

我有一個c#工廠對象,它使用對象列表作爲源通過工廠方法創建對象。工廠對象因自身依賴性而導致stackoverflowexception

對象的列表中創建這樣的:我的應用程序訪問

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

     //Add all widgets 
     widgetLibrary.Add(new ClientsWidget()); 
     widgetLibrary.Add(new InstallationsWidget()); 
     etc. 

和各種零件此列表以不同的方式來獲得它需要的對象的類型。

但是我現在要求列表中的一個對象(即一個小部件)需要使用這個小部件工廠本身。顯然這會導致循環引用。

我該如何改變我的設計以適應這種需求?

回答

4

但我現在已經在列表中的對象(即一個widget)的一個需要利用小部件工廠本身的要求。顯然這會導致循環引用。

我該如何改變我的設計以適應這種需求?

通常情況下,對象不應該依賴建造它們的工廠,因爲它會導致這個問題。如果您可以將參考文獻推入工廠,但在需要之前不使用它,則可能會解決問題。

如果你絕對需要這樣做,那麼最好的方法可能是懶惰地實例化工廠內的對象。您可以使用List<Lazy<WidgetModel>>而不是讓您的WidgetFactory內部包含List<WidgetModel>。這將允許單個「小部件」僅根據需要進行評估,這意味着,當有問題的小部件試圖引用工廠時,它將被完全加載。

+0

第一個想法起作用了,我只需要在這個環境中使用工廠時多加小心。 –

0

對於初學者,將Widget創建移出WidgetFactory的構造函數。這應該發生在初始化方法中,或者在CreateWidget(Type)方法中按需執行。

爲了使工廠實例提供給控件實例,你可以做一些不同的事情之一:

  1. 有WidgetFactory通「這個」時,它創建了Widget
  2. 使用Singleton模式:添加一個靜態屬性WidgetFactory.Instance並初始化一次;讓所有WidgetFactory用戶都可以訪問該屬性,而不是創建新的實例。
  3. 使用dependency injection模式 - 很難在此處提供簡短描述。
+0

對不起,你只是扔了一些流行語,希望其中一個是正確的? – jason

+0

@Jason ha!不,但我明白你爲什麼這麼說。這兩種方法都是OP問題的有效解決方案,但我想我的答案可以使用更多細節。 – alexdej

1

但是我現在要求列表中的一個對象(即一個控件)需要使用控件工廠本身。顯然這會導致循環引用。

我該如何改變我的設計以適應這種需求?

您的模型是錯誤的。一旦汽車離開了NUMMI工廠的裝配線,它就不依賴於工廠的正常運行。

此外,我質疑你的工廠的設計。爲什麼你的構造函數是new實例。該服務的目的是什麼?

您應該多告訴我們一些關於您的模型的更多信息,以及爲什麼您認爲您需要這個模型。賠率是,正確完成,你沒有。

+0

使用這個比喻,被驅動的對象是另一個汽車工廠。該工廠正在爲UI元素創建模型,但我現在需要創建映射到工廠的UI元素。那有意義嗎? –

+0

@Jon Eastwood:聽起來像這個工廠做得太多了(建設工廠和UI小部件?)。你應該分清責任。 – jason

1

WidgetFactory的構造函數不應該調用正在構建的東西的構造函數。相反,WidgetFactory應該有一個完成所有工作的方法(BuildWidgets)。

然後,其他對象可以使工廠的一些使用,而不會導致這個級聯的活動重新開始。

+0

我同意這一點,我認爲這是問題的根源,但我不知道如何改變它。我需要一種枚舉工廠可以創建的對象的可能類型的方法,而不必爲每個對象明確地編寫構建方法。 –