2010-03-19 106 views
2

我寫了從System.Diagnostics.TraceListener衍生像這樣添加跟蹤方法System.Diagnostics.TraceListener

public class Log : TraceListener 

這作爲包裝日誌類log4net的,並允許人們使用System.Diagnostics程序像追蹤所以

Trace.Listeners.Clear(); 
Trace.Listeners.Add(new Log("MyProgram")); 
Trace.TraceInformation("Program Starting"); 

有添加額外的跟蹤級別,則默認跟蹤那些(錯誤,警告,信息)

我想有這個加入到運營商的請求ystem.Diagnostics.Trace所以它可以使用像

Trace.TraceVerbose("blah blah"); 
Trace.TraceAlert("Alert!"); 

有沒有什麼辦法可以做到這一點與擴展類?我試圖

public static class TraceListenerExtensions 
{ 
    public static void TraceVerbose(this Trace trace) {} 
} 

,但什麼都沒有的跟蹤實例暴露:(傳遞

回答

10

這是爲時已晚,但你有沒有考慮過使用TraceSource? TraceSources爲您提供實際的對象實例,您可以使用它們登錄System.Diagnostics(這意味着您可以使用擴展方法擴展它們,就像您在問題中提出的那樣)。 TraceSources通常在app.config中配置(類似於您將如何配置log4net記錄器)。您可以控制日誌記錄的級別以及哪些跟蹤偵聽器正在偵聽。所以,你可以有應用程序代碼,編程對TraceSource,這可能看起來是這樣的:

public class MyClassThatNeedsLogging 
{ 
    private static TraceSource ts = 
      new TraceSource(MethodBase.GetCurrentMethod().DeclaringType.Name); 
    //Or, to get full name (including namespace) 
    private static TraceSource ts2 = 
      new TraceSource(MethodBase.GetCurrentMethod().DeclaringType.FullName); 

    private count; 

    public MyClassThatNeedsLogging(int count) 
    { 
    this.count = count; 

    ts.TraceEvent(TraceEventType.Information, 0, "Inside ctor. count = {0}", count); 
    } 

    public int DoSomething() 
    { 
    if (this.count < 0) 
    { 
     ts.TraceEvent(TraceEventType.Verbose, 0, "Inside DoSomething. count < 0"); 
     count = Math.Abs(count); 
    } 

    for (int i = 0; i < count; i++) 
    { 
     ts.TraceEvent(TraceEventType.Verbose, 0, "looping. i = {0}", i); 
    } 
    } 
} 

您還可以創建使用任何名稱TraceSources(即它不必是類名):

TraceSource ts1 = new TraceSource("InputProcessing"); 
TraceSource ts2 = new TraceSource("Calculations"); 
TraceSource ts3 = new TraceSource("OutputProcessing"); 

正如我前面提到的,每個TraceSource通常配置在app.config文件中,以及日誌「級別」和應該接收輸出的偵聽器。

爲了您的擴展方法,你可以做這樣的事情:

public static class TraceSourceExtensions 
{ 
    public static void TraceVerbose(this TraceSource ts, string message) 
    { 
    ts.TraceEvent(TraceEventType.Verbose, 0, message); 
    } 
} 

如果你需要做的TraceSource的更多個性化(如添加額外的水平),這是描述如何做一個相當不錯的文章即:

http://msdn.microsoft.com/en-us/magazine/cc300790.aspx

如果最終使用的log4net您的TraceListener內(並用它來定義一個名爲記錄器,日誌記錄級別等),你可能並不需要配置許多TraceSources。您甚至可以只配置一個(其名稱將是衆所周知的),或者您可以以編程方式創建一個,將其設置爲記錄「全部」,然後將其連接到特定的TraceListener。

最後,您可以不通過靜態Trace對象進行日誌記錄,而是可以通過TraceSource實例登錄。如果配置了一個TraceSource和它的名字是衆所周知的,有效的TraceSource可以創建(用於日誌記錄)的任何地方像這樣:

TraceSource ts = new TraceSource("logger"); 
ts.TraceEvent(TraceEventType.Information, 0, "Hello World!"); 
//Or, via your extension method 
ts.TraceVerbose(TraceEventType.Verbose, 0, "Logged via extension method"); 

可能有更好的方法來完成你正在試圖完成的任務,但是這可能會給你一些關於使用TraceSource與靜態Trace類的思考。

-1

你的問題是,你不能添加擴展方法作用於靜態類。擴展方法的第一個參數。它應該在操作實例由於Trace類是靜態的,不存在這樣的情況下你可能最好創建自己的靜態日誌的包裝,露出你想擁有的方法,如TraceVerbose

public static class LogWrapper 
{ 
    public static void TraceVerbose(string traceMessage) 
    { 
     Trace.WriteLine("VERBOSE: " + traceMessage); 
    } 
    // ...and so on... 
} 

這也將解耦你從實際的日誌記錄框架中使用日誌代碼,這樣你可以稍後從跟蹤日誌切換到使用log4net或其他東西,如果你想。

+1

然後問題是每個人都必須使用我的記錄器。通過在日誌框架內工作,人們可以使用它。例如System.Diagnostics.Trace.TraceWarning(「warning!」)。此外,使用System.Diagnostics.Trace的任何第三方程序集都會自動將消息發送到我們的記錄器,而無需修改。 – Kenoyer130 2010-03-19 18:16:54