2017-02-22 100 views
0

我們有一個外部項目,它具有一個QCServiceLog類,具有由Unity解析的ILogging依賴關係。 但QCServiceLog是一個Singleton類,你可以在下面的例子中看到:具有依賴注入的單例類c#

private readonly ILogging _logging = null; 

private static QCServiceLog _instance = null; 
public static QCServiceLog Instance 
{ 
    get 
    { 
     return _instance; 
    } 
} 

public QCServiceLog(ILogging logging) 
{ 
    _logging = logging; 
    if (_instance == null) 
    { 
     _instance = this; 
    } 
} 

我們正在嘗試使用它,並在我們的解決方案,我們做了登記,如:

uc.RegisterType<ILogging, QCFileManager>(new ContainerControlledLifetimeManager()); 

但由於QCServiceLog是一個Singleton,我們相信代碼永遠不會通過構造函數,然後_instance永遠不會被實例化。 我們正在使用它這樣做:

QCServiceLog.Instance.Log(ex); 

那是辛格爾頓正確實施?我們認爲它從未做過QCServiceLog的新的

您認爲如何?在沒有改變外部項目的情況下,我們可以做什麼? 您可以想象的例外是:

未將對象引用設置爲對象的實例。

我真的很感謝你的幫助!

回答

1

Singleton是否正確實施?

是的。但是它需要先從容器實例化,然後才能獲得靜態實例。

換句話說,你不能使用此行:

QCServiceLog.Instance.Log(ex); 

,直到第一次調用:

container.Resolve<QCServiceLog>(); 

(假設你已經註冊的ILogging使用Unity的實例),因爲第一調用不會觸及構造函數來填充_instance值。

你可能好不需要的地方直接將其注入:

public class Foo(QCServiceLog log) 

或可選擇地使包含通過您的DI容器注入在使用之前,正確連接起來的邏輯的包裝類。

無論採用哪種方式,您都應該注意DI主要用於您的應用。第三方實用程序不一定以DI友好的方式執行任何操作,因此您可能需要使用facadeadapter以使它們適合在應用程序環境中使用。

1

您所提供的代碼是不是線程安全的 - 看看這裏Implementing the Singleton Pattern in C#:其他

public QCServiceLog(ILogging logging) 
{ 
    _logging = logging; 
    if (_instance == null) 
    { 
     _instance = this; 
    } 
} 

一個問題是構造方法中沒有隱藏。因此,即使您的IoC容器將該類註冊爲Singleton,也可以使用new運算符在代碼中的任何位置構造此類的實例。我發現在我工作的應用程序中發生了內存泄漏,這是由於這件事造成的(意圖是通過DI/IoC使用,它被註冊爲單例,但是通過手動代碼進行了更新。)