1. ホーム
  2. design-patterns

Dependency Injectionでlog4netを利用する方法

2023-07-18 16:15:01

質問

依存性注入フレームワークでlog4netの正しいパタンと使い方を把握しようとしています。

Log4NetはILogインターフェイスを使用しますが、私は、Log4Netを呼び出す必要があります。

LogManager.GetLogger(Reflection.MethodBase.GetCurrentMethod().DeclaringType)

を、情報を記録する必要がある各クラスやメソッドに追加します。これはIoCの原則に反しているようで、Log4Netを使用するように私に結合しています。

抽象化の別のレイヤーをどこかに入れるべきでしょうか?

また、現在のユーザー名のようなカスタムプロパティをこのように記録する必要があるのですが。

log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;

どのようにカプセル化すれば、毎回それをすることを覚える必要がなく、かつログを記録している現在のメソッドを維持することができます。このようなことをするべきか、それとも完全に的外れなのか?

public static class Logger
{
    public static void LogException(Type declaringType, string message, Exception ex)
    {
        log4net.ThreadContext.Properties["userName"] = ApplicationCache.CurrentUserName;
        ILog log = LogManager.GetLogger(declaringType);
        log.Error(message, ex);
    }
}

どのように解決するのですか?

あなたは、木を見て森を見ずといったところでしょうか。 ILog と LogManager は、Apache コモンズ ロギングとほぼ 1 対 1 で等価な軽量ファサードであり、実際にあなたのコードを log4net の残りに結合するわけではありません。

<rant>

また、私は ほとんど常に フレームワークの重要で有用な機能を失うか、有用な情報を失うか、簡略化された ILog インターフェースでさえ使用できるパフォーマンスの向上を失うか、またはそのすべてです。 言い換えれば log4net との結合を避けるために log4net をラップすることはアンチパターンです。 .

</rant>

インジェクションの必要性を感じる場合は、ロガーインスタンスをプロパティ経由でアクセスできるようにしてインジェクションを可能にしますが、昔ながらの方法でデフォルトのインスタンスを作成します。

すべてのログメッセージにコンテキストの状態を含めることに関しては、グローバルプロパティを追加する必要があります。 ToString() で解決されるグローバルプロパティを追加する必要があります。 例として、現在のヒープ サイズの場合。

public class TotalMemoryProperty
{
    public override string ToString()
    {
        return GC.GetTotalMemory(false).ToString();
    }
}

そして、起動時に差し込むこと。

GlobalContext.Properties["TotalMemory"] = new TotalMemoryProperty();