3

System.Diagnostics.TraceListener から派生した Log クラスを次のように作成しました

public class Log : TraceListener

これは Log4Net のラッパーとして機能し、System.Diagnostics Tracing をそのように使用できるようにします。

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

デフォルトのトレース レベル (エラー、警告、情報) に加えて、追加のトレース レベルを追加する要求があります。

これを System.Diagnostics.Trace に追加して、次のように使用できるようにしたい

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

拡張クラスでこれを行う方法はありますか? 私は試した

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

しかし、渡されたトレースインスタンスには何も公開されていません:(

4

2 に答える 2

11

これはかなり遅れていますが、TraceSource の使用を検討しましたか? TraceSources は、System.Diagnostics にログを記録するために使用できる実際のオブジェクト インスタンスを提供します (つまり、質問で提案したように、拡張メソッドでそれらを拡張できます)。通常、TraceSource は 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);
    }
  }
}

任意の名前を使用して TraceSource を作成することもできます (つまり、クラス名である必要はありません)。

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

最終的に TraceListener 内で log4net を使用する場合 (およびそれを使用して名前付きロガー、ログ レベルなどを定義する場合)、多くの TraceSource を構成する必要はないかもしれません。1 つだけを構成することもできます (その名前はよく知られています)、またはプログラムで作成し、「すべて」をログに記録するように設定して、特定の TraceListener に接続することもできます。

最後に、静的 Trace オブジェクトを介してログを記録する代わりに、TraceSource インスタンスを介してログを記録できます。1 つの 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 クラスの使用に関して考えることができるかもしれません。

于 2010-08-25T15:50:09.703 に答える
-1

あなたの問題は、静的クラスに作用する拡張メソッドを追加できないことです。拡張メソッドの最初のパラメーターは、操作対象のインスタンスです。Traceクラスは静的であるため、そのようなインスタンスはありません。おそらく、独自の静的ログ ラッパーを作成して、次のような必要なメソッドを公開する方がよいでしょうTraceVerbose

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

これにより、使用中の実際のロギング フレームワークからロギング コードを切り離すこともできるため、必要に応じて、後でトレース ロギングから log4net などの使用に切り替えることができます。

于 2010-03-19T17:18:33.733 に答える