2016-08-10 10 views
2

私は、テキストにログするために使用できるロガーAPIを持っています。 ロガーには、enventタイプ(Info、Errなど)、ソースapp(app1、app2、etc ...)とmesgテキストの記録に使用できるプロパティがいくつかあります。別のクラスを使用する静的クラス

構文は簡単で、OK取り組んでいる:

Logger log = new Logger(); 
log.Write("Information", "SourceApplication", "Test text to log"); 

今私は2つの静的クラス、「汎用ログ」用と「デバッグログ」の他の作成を考えメートル。目標は、モジュール使用率ごとにロガーオブジェクトの新しいインスタンスを作成しないようにすることです。各クラスはインスタンス化せずにこれらのオブジェクトを使用できる必要があります(静的クラスは自動的にそれを処理する必要があります)。

"デバッグログ" - ソリューション内のプロジェクトで使用でき、シングルトンである必要があります。発信者コードを使用する は次のようになります。

LoggerDebug.Write("Debug", "Debugger", "Test text to log"); 

汎用ログ - Loggerオブジェクト を処分しなければならない静的クラスのすべてのプロジェクトのモジュールではなく、各利用後に使用するために使用する発信者のコードは次のようになります。

LoggerDebug.Write("Information", "App1", "Test text to log"); 

私は、「デバッグログ」で静的クラスを開始しようとしました、私は読んで(http://csharpindepth.com/Articles/General/Singleton.aspx)が、I`mが、これはこれを行うには正しい方法であるかどうかわからない... あなたは私にいくつかの提案を与えることはできますか?

が発生した 'System.NullReferenceException' 種類の未処理の例外を:私はそれがでクラッシュしたアプリケーションを実行しようとすると

LoggerDebug.Write("Information", "App1", "Test text to log"); 

using System; 
using System.Diagnostics; 
using System.Collections.Generic; 

namespace Common 
{ 
    public sealed class LoggerDebug 
    { 
     private static LoggerDebug instance = null; 
     private static readonly object padlock = new object(); 
     private static Logger log; 

     static LoggerDebug Instance 
     { 
      get 
      { 
       lock (padlock) 
       { 
        if (instance == null) 
        { 
         instance = new LoggerDebug(); 
        } 
        return instance; 
       } 
      } 
     } 

     public LoggerDebug() 
     { 
      log = new Logger(); 
     } 

     public static void Write(String EventType, string appSource, string text) 
     { 
      log.Write(EventType, appSource, string.Format("Test {0}", text)); 
     } 
    } 
} 

発信者コードは次のように表示されますCommon.dllで追加情報:オブジェクト参照がオブジェクトのインスタンスに設定されていない 。

private static Logger log = new Logger(); 

そしてCTORコード

public LoggerDebug() 
{ 
    //log = new Logger(); 
} 

のコメントしかし、私は混乱してメートル:ctorのは、だから、私はこの問題を修正することができますlog = new Logger();

をインスタンス化されていないと述べた

、これを行う正しい方法であるかどうかは分かりません。これを正しく行うにはどうすればいいですか?

私が使用できる例はありますか?

+3

サイド質問:なぜホイールを再発明するのですか? .NETには、[Log4Net](https://logging.apache.org/log4net/)と[NLog](http://nlog-project.org/)という2つの優れたログフレームワークがあります。 – Igor

+0

静的インスタンスは呼び出されません。 –

+0

静的メソッド "Write"内に新しいインスタンスを作成するだけです。 – Fabio

答えて

1

ここには更新されたコードがあります。インスタンスメンバー/メソッドが存在しないので、すべてを静的にします。コード内のコメントを参照してください。

私は強くお勧めします学習経験以外のためにこれを行うにはありません。高度に構成可能で広くテストされているLog4NetやNLogのような既存のフレームワークを使用する。

using System; 
using System.Diagnostics; 
using System.Collections.Generic; 

namespace Common 
{ 
    // changed sealed to static as there are no instances 
    public static class LoggerDebug 
    { 
     // removed lock object 
     private static Logger log; 

     // added static constructor 
     static LoggerDebug(){ 
      log = new Logger(); 
     } 

     // no need for lock due to static constructor 
     // removed Instance 
     // removed instance constructor 

     public static void Write(String EventType, string appSource, string text) 
     { 
      log.Write(EventType, appSource, string.Format("Test {0}", text)); 
     } 
    } 
} 

シングルトンパターンを使用することもできますが、使用するには少なくとも1つのインスタンスレベル(非静的)メンバーが必要です。

using System; 
using System.Diagnostics; 
using System.Collections.Generic; 

namespace Common 
{ 
    // changed sealed to static as there are no instances 
    public sealed class LoggerDebug 
    { 
     // removed lock object 
     private static Logger log; 

     // added static constructor 
     static LoggerDebug(){ 
      log = new Logger(); 
      _logger = new LoggerDebug(); 
     } 

     // singleton that is created only once 
     private static LoggerDebug _logger; 
     public static LoggerDebug Logger{ 
      get{return _logger;} 
     } 

     // removed static keyword 
     public void Write(String EventType, string appSource, string text) 
     { 
      log.Write(EventType, appSource, string.Format("Test {0}", text)); 
     } 
    } 
} 

また、静的フィールドをインラインで初期化することもできます。理想的には、可能な競合状態とすべてのインスタンスに対して実行されるチェックを書き込む必要があるため、インスタンスレベルメンバーの静的フィールドを初期化することは決して望ましくありません。効率的でなく、脆弱なコードになります。

+0

大きな助け...それは私の頭の中でいくつかの事を明確にしています...ありがとう:) – user6495763

+0

@ user6495763 - 喜んで助けてください。左のサイトのチェックボックスを使用して、それを回答とマークしてください(そうであれば)。 – Igor

+0

最初のサンプル "static class"には、C#によって自動的に処理されるオブジェクトインスタンス "new Logger()"がありますか? – user6495763

関連する問題