2010-10-21 127 views
4

我有一個c#web服務。當我得到一個新的請求時,我創建一個日誌記錄實例。我有很多其他類的實例來處理請求,我也希望它們能夠記錄。共享日誌記錄實例而不將其傳遞給構造函數或屬性的最佳方式是什麼?如何與多個類共享一個類的實例?

+0

你正在使用什麼日誌框架? – 2010-10-21 23:59:07

+2

下面的答案很好(基本上使用一個靜態實例,由單身守衛)。不過,可以考慮使用DI容器來管理它。使每個人的生活更輕鬆。 – RPM1984 2010-10-22 00:06:47

回答

3

Singleton Pattern is an anti-pattern;我無法想象應該使用或推薦使用或推薦的很多情況,包括在這種情況下,用於日誌記錄。

我們如何處理日誌記錄:通過構造器注入將日誌記錄實例注入到所有需要它的類中。例如:

public class MyClass 
{ 
    private readonly ILogger _logger; 

    public MyClass(ILogger logger) 
    { 
     _logger = logger; 
    } 

    public void DoStuff() 
    { 
     _logger.Trace("DoStuff called"); 
    } 
} 

測井例如注射,每次可以是一個新的實例,或者如果你是在具有可創建一次,並通過根據需要在單個實例記錄器彎曲。

但是,我強烈建議第一個選項,使用DI來構建您的類使用Composition Root模式。我還建議使用日誌框架,例如NLog或log4net。這些可配置並易於使用的電子郵件,事件查看器,文件等。在多線程環境中工作。

我們有自己定義的ILogger,它有Trace,Warn,Info,Exception等等,然後用NLog實現這個接口。這意味着我們可以通過創建ILogger的新實現並進行簡單的DI配置更新來輕鬆更改我們的日誌記錄。這是迄今爲止我們工作得很好的一種日誌記錄解決方案。

+0

這是一種劣質的方法 - 尤其是如果你有幾個類似的要求,你的構造者看起來很荒謬。它遠遠優於讓你的班級具有智慧並且能夠自主決定他們的環境。整個DI理論是業餘的,馬虎的。靜態類沒有什麼問題,如果你正在編寫c#,那麼當你引用任何MS核心程序集時,你已經完全綁定了它們。 String.Format() - 等...不妨使用Logging.Log() – hajikelist 2015-05-11 16:27:11

0

那麼,你可以讓你的日誌記錄類包含靜態方法,這些方法將實際寫入內存/刷新到磁盤。你也可以看看Singleton Pattern

-1

使用一個靜態字段(我假設C#支持這些)。語法應該與此類似:

private static final Logger logger = new Logger(...); 

並且只要您需要在課程中記錄某些內容時使用它。

+0

我認爲你的意思是隻讀而不是最後? – 2010-10-22 00:00:21

+0

我是Java開發人員。這對我們來說是'最後的'。 ;-)。是的,那是我的最終答案.... – 2010-10-22 00:23:49

0

您可以使用Singleton Pattern確保整個系統中只有一個記錄對象實例。

將日誌對象傳遞給構造函數或屬性實際上會使您的代碼更易於測試,具體取決於您如何實現Singleton模式。日誌記錄是那些令人煩惱的交叉問題之一,總是有權衡。

0

通常在每個班級中創建記錄器的新實例並不是問題。 Log4Net記錄器構造函數採用一種類型作爲參數,爲您提供更好的日誌。

3

通常某種靜態類/屬性的用於共享的對象,而無需到處通過引用,例如:

public class Logger 
{ 
    static Logger() 
    { 
     this.Instance - new Logger(); 
    } 

    public static Logger Instance 
    { 
     get; 
     private set; 
    } 

    // Other non-static members 
} 

用法:

Logger.Instance.Log(); 

通常這種(或至少在此變化)被稱爲singleton pattern

上有上述許多變化,例如下列細微變化是比在日誌框架上述多見:

public class Logger 
{ 
    static Logger() 
    { 
     this.Instance = new Logger(); 
    } 

    public static Logger Instance 
    { 
     get; 
     private set; 
    } 

    public static void Log() 
    { 
     Logger.Instance.Log(); 
    } 
} 

用法:

Logger.Log(); 
+0

這是一個最佳解決方案;把Logger放在自己的庫中,這樣你就可以從其他項目中引用它。 – 2010-10-22 00:38:21

2

Singleton模式。

也就是說,一個具有私有構造函數的類。您使用公共靜態方法僅創建該類的一個實例並返回該對象。

編輯:另外值得注意的是,您需要將此類放在其自己的項目中,以便它可以被所有類引用。

相關問題