10

Common.Logging for .NETを使用するプロジェクトを調べていると、いくつかのクラスがロガー インスタンスをクラスの静的メンバーとして宣言していることに気付きました。例えば:

public class HelloJob : IJob
{
    private static ILog _log = LogManager.GetLogger(typeof(HelloJob));

    public HelloJob()
    {
    }

    public virtual void  Execute(IJobExecutionContext context)
    {
        _log.Info(string.Format("Hello World! - {0}", System.DateTime.Now.ToString("r")));
    }
}

他のクラスでは、ロガーはインスタンス メンバーとして宣言されます。

public class SimpleExample : IExample
{
    public virtual void Run()
    {
        ILog log = LogManager.GetLogger(typeof (SimpleExample));

        log.Info("------- Initializing ----------------------");

        // etc
    }
}    

いずれかのアプローチを好む理由はありますか?

どのような場合にそれぞれのアプローチが推奨されますか? スレッドセーフに関連していますか?

静的な「ロガー」メンバーを持つ「ロガー」クラスを宣言し、プロジェクト全体でそれを使用した場合、問題になるでしょうか (実際にはグローバル変数を持つという問題は別として)。

4

1 に答える 1

12

ほとんどのロガーはスレッドセーフであり、それらのインスタンスを作成することは、時間とメモリの両方の点でほとんどオーバーヘッドがありません。したがって、本当の問題は、プログラミングと保守性の観点から何が理にかなっているのかということです。

一方では、ロガーは概念的にクラスのインスタンスではなくクラスに関連付けられているため、多くの人はそれを静的に保つことを好みます。それは完全に有効な議論です。たとえば、extendsの場合、より具体的なサブクラスインスタンスがある場合でも、ほとんどの人はコードで記述されたログメッセージがクラスに関連付けられることを期待すると思います。また、静的メソッドからロガーにアクセスできるのも便利です。これは、静的フィールド上にない場合はアクセスできません。HelloWorldJobHelloJobHelloJobHelloJob

一方、HelloJobが独自のロガーインスタンスの取得を担当する必要がある理由はありません。代わりに依存性注入を使用することについては、多くのことを言わなければなりません(ユニットのテスト可能性、追加の構成可能性、およびより単純なコード)。したがって、私は個人的に、ロガーをDIフレームワークによって注入することをお勧めします。その場合、インスタンスごとのフィールドで参照する必要があります。

public class HelloJob : IJob
{
    private readonly ILog _log;

    public HelloJob(ILog log)
    {
        _log = log;
    }
    ...
}

DIフレームワークは、実行時に認識している詳細に基づいてロガーを設定できます。または、単体テストで偽のロガーまたはモックロガーを提供して、期待されるログメッセージが生成されることを確認できます。インスタンスごとのフィールドを参照している場合でも、クラスごと(またはシングルトン)のインスタンスを完全に自由に使用できることに注意してください。これらは、このクラスの一部である必要のない詳細にすぎません。懸念。

アップデート

時間の経過とともに、私は静的ロガーを使用する方向に意見をシフトしてきました。具体的には、Fody Anotarライブラリを使用して静的ロガー(およびその他の役立つコード)を生成するのが本当に好きなので、ソースコードに書き込む必要があるのは次のようなログステートメントだけです。

LogTo.Info("This is a message");
于 2012-12-04T23:48:13.077 に答える