2014-01-31 17 views
0

我在我的課程中只有一個副本。我不想使用Singleton模式,原因有很多(*見下文)。我知道我只會有一個類的副本,因爲我將是唯一一個調用它的構造函數。這是一個很好的方法來檢查是否只有一個類的實例存在,而不訴諸使用Singleton模式?

在我的類的構造函數中,我想檢查該類的只有一個副本是否存在,並在存在多個類時拋出異常。下面的代碼是否適合用於這種情況?

public class MySingletonAlternative : IDisposable 
{ 
    private static int _count = 0; 

    public MySingletonAlternative() 
    { 
     int newValue = System.Threading.Interlocked.Increment(ref _count); 
     if (newValue > 1) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public void Dispose() 
    { 
     int newValue = System.Threading.Interlocked.Decrement(ref _count); 
     if (newValue < 0) 
     { 
      throw new ObjectDisposedException("MySingletonAlternative"); 
     } 
    } 
} 

*我爲什麼不想使用單例:

  1. 我希望能夠創建該類時控制。在傳統的C#單例模式中,構造發生非確定性。

  2. 我想避免全局變量。

  3. 當我調試我的代碼並在Singleton的私有構造函數中引發異常時,Visual Studio會突出顯示該異常,但它會突出顯示錯誤的代碼行,通常位於不同的文件中。

  4. 我不想懶惰地創建這個對象(使用Lazy <T>)。這個類的一個實例將存在於我的應用程序的生命中。我通過懶惰地構建它而獲益匪淺。

+2

如果你有一個靜態構造函數,正常單的建設是完全確定的。而你仍然有一個全局變量:計數器。一點也不清楚*爲什麼*要阻止創建多個實例。這有一些單身模式的缺點(例如缺乏可測試性),沒有一些可疑的好處。 –

+0

根據http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx用戶無法控制何時在程序中執行靜態構造函數。另外,我不會將全局計數器考慮到我宣佈它是私密的。 – user2023861

+0

這只是不真實的。對於沒有存在靜態構造函數的類型,它的類型初始值設定項有些* true,但是當存在靜態構造函數時,C#規範非常明確:「執行靜態構造函數是由以下事件中的第一個觸發的:應用程序域: - \t創建類類型的實例 - 引用任何類類型的靜態成員。「 –

回答

0

使用IoC容器,如UnityContainer。它會消除你提到的所有觀點,你爲什麼不想使用單例(用全局變量或static)。您將能夠完全控制您的生命週期實例的創建,並將其注入到所有需要使用此類的類中。

0

你可以使用依賴注入,然後讓di容器管理你想創建的類的生命週期嗎?一個例子是使用Unity和ContainerControlledLifetimeManager

http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx#sec34

+0

我認爲依賴注入解決方案比我需要的更強大。我也不確定這會解決我的問題。我的項目很小,我不會經常更換組件或依賴項。我的問題最終是我的應用程序的生命中需要一個類的實例。這門課掌握一些數據並進行網絡通話。我不想要重複的數據或不必要的網絡呼叫;因此恰好是該類的一個實例。 – user2023861

+1

DI不大或難以添加到您的項目中。從你所說的話,它將解決你所列出的所有問題,而不僅僅是基於配置交換事情 - 但是使你以更可測試的方式編寫代碼,同時消除單身類固有的邪惡,因爲它是可能的讓您的應用程序的這方面爲您管理。事實上,如果你不習慣DI,那麼在一個小項目中開始使用DI是最容易掌握的方法。無論如何,祝你好運! – Jay

+0

這很有趣,我打算使用MySingletonAlternative的方式類似於我已閱讀的有關依賴注入示例的內容。直到你提到它,我才知道它被稱爲。我在網上閱讀過的例子看起來對我來說太強大了,但是我想用類來處理需要我一生的對象的例子是他們有一個setter,我將使用它來設置這個依賴關係, (構建生命週期對象需要一點點時間)。謝謝。 – user2023861

相關問題