我有一個c#web服務。當我得到一個新的請求時,我創建一個日誌記錄實例。我有很多其他類的實例來處理請求,我也希望它們能夠記錄。共享日誌記錄實例而不將其傳遞給構造函數或屬性的最佳方式是什麼?如何與多個類共享一個類的實例?
回答
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配置更新來輕鬆更改我們的日誌記錄。這是迄今爲止我們工作得很好的一種日誌記錄解決方案。
這是一種劣質的方法 - 尤其是如果你有幾個類似的要求,你的構造者看起來很荒謬。它遠遠優於讓你的班級具有智慧並且能夠自主決定他們的環境。整個DI理論是業餘的,馬虎的。靜態類沒有什麼問題,如果你正在編寫c#,那麼當你引用任何MS核心程序集時,你已經完全綁定了它們。 String.Format() - 等...不妨使用Logging.Log() – hajikelist 2015-05-11 16:27:11
那麼,你可以讓你的日誌記錄類包含靜態方法,這些方法將實際寫入內存/刷新到磁盤。你也可以看看Singleton Pattern
使用一個靜態字段(我假設C#支持這些)。語法應該與此類似:
private static final Logger logger = new Logger(...);
並且只要您需要在課程中記錄某些內容時使用它。
我認爲你的意思是隻讀而不是最後? – 2010-10-22 00:00:21
我是Java開發人員。這對我們來說是'最後的'。 ;-)。是的,那是我的最終答案.... – 2010-10-22 00:23:49
您可以使用Singleton Pattern確保整個系統中只有一個記錄對象實例。
將日誌對象傳遞給構造函數或屬性實際上會使您的代碼更易於測試,具體取決於您如何實現Singleton模式。日誌記錄是那些令人煩惱的交叉問題之一,總是有權衡。
通常在每個班級中創建記錄器的新實例並不是問題。 Log4Net記錄器構造函數採用一種類型作爲參數,爲您提供更好的日誌。
通常某種靜態類/屬性的用於共享的對象,而無需到處通過引用,例如:
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();
這是一個最佳解決方案;把Logger放在自己的庫中,這樣你就可以從其他項目中引用它。 – 2010-10-22 00:38:21
Singleton模式。
也就是說,一個具有私有構造函數的類。您使用公共靜態方法僅創建該類的一個實例並返回該對象。
編輯:另外值得注意的是,您需要將此類放在其自己的項目中,以便它可以被所有類引用。
- 1. 幾個類共享另一個類的實例
- 2. ASMX服務共享單個類實例
- 3. 共享一個PrintDocument實例
- 4. 如何:多個Django實例共享一個全局變量?
- 5. 在C#中的多個對象之間共享一個實例化的類
- 6. 如何在C#中的一個類的多個實例之間共享一個值?
- 7. 是否有多個類實例共享此列表?
- 8. 如何與多個html文件共享javascript websocket實例
- 9. 共享變量的多個ScriptControl實例
- 10. PHP - 如何跨多個子類共享設置並實例化這些共享設置一次?
- 11. 與另一個控件共享屬性的一個實例?
- 12. 如何使用類方法分發UIManagedDocument的多個共享實例?
- 13. 一個片段類的多個實例
- 14. 的iOS:保留一個共享實例
- 15. 如何在多個操作中共享一個對象的單個實例?
- 16. 在一個類的所有實例之間共享一個變量
- 17. Dos同一個MovieClip的多個實例共享Cache嗎?
- 18. 如何實現一個具有多個獨立公共接口的案例類?
- 19. 如何與多個目標c類共享xib文件
- 20. 如何從Actionscript 3.0中的另一個類實例引用一個類實例?
- 21. 一個類實例
- 22. 具有多個類的C++共享庫
- 23. 如何在另一個類中創建一個類的實例
- 24. 在類實例中共享變量
- 25. Python OOP:如何與所有類共享一個MongoDB連接
- 26. 如何創建一個css類的多個實例?
- 27. 如何創建一個類的多個實例?
- 28. 如何在C++中創建一個類的多個實例
- 29. 如何刪除一個類的實例?
- 30. 如何返回一個類的實例?
你正在使用什麼日誌框架? – 2010-10-21 23:59:07
下面的答案很好(基本上使用一個靜態實例,由單身守衛)。不過,可以考慮使用DI容器來管理它。使每個人的生活更輕鬆。 – RPM1984 2010-10-22 00:06:47