0
class LogUtil<T> : ILogUtility
{
    log4net.ILog log;

    public LogUtil()
    {
        log = log4net.LogManager.GetLogger(typeof(T).FullName);
    }

    public void Log(LogType logtype, string message)
    {
        Console.WriteLine("logging coming from class {0} - message {1} " , typeof(T).FullName, message);
    }
}

public class Logger
{
    ILogUtility _logutility;

    public Logger(ILogUtility logutility)
    {
        _logutility = logutility;
    }


    public void Log(LogType logtype, string message)
    {
        _logutility.Log(logtype, message);
    }


}

柔軟性があり、将来LogUtilクラスを削除して、他のものを使用する機能が必要です。

したがって、LoggerUtilityラッパークラスを次のように記述します。

class LoggerUtility<T>
{
    public Logger logger
    {
        get
        {

            LogUtil<T> logutil = new LogUtil<T>();

            Logger log = new Logger(logutil);

            return log;
        }
    }
}

私のクライアントコードは次のとおりです。

public class TestCode
{
    public void test()
    {

        new LoggerUtility<TestCode>().logger.Log(LogType.Info, "hello world");

    }

}

クリーンではない可能性のあるLoggerプロパティをコーディングしています。

次の行がきれいに見えないことがわかります。

new LoggerUtility<TestCode>().logger.Log(LogType.Info, "hello world");

クライアントコードを書くためのより良い方法はありますか?LogUtilとの結合を緩め、クライアントコードで直接使用したくない。

私にお知らせください。

ありがとう

4

2 に答える 2

2

ILogUtilコメントで提供された答えは正しいです(クライアントは、具体的な実装ではなく、インターフェースに直接依存する必要があります)。他にも無数の問題があります:

  • メッセージをログに記録するたびに、LoggerUtility<T>クラスクラスの新しいインスタンスをインスタンス化します。Loggerおそらくここの何かは静的でなければなりませんか?余分なレイヤー(LoggerUtility)のポイントは何ですか?

  • ジェネリックス(LoggerUtility<T>)を使用しても、完全に意味がありません。これは、型だけに縛られるTことはなく、その情報を利用しないためです。

実際には、独自のロギングファサードを作成することは、他の人がすでに費やした努力です。既存の実装を使用するだけです。との両方log4netを保証することもできNLogますが、柔軟性を持たせたい場合は、前述の実装用のアダプターを備えたCastle.Services.Loggingの適切なファサードを選択してください(独自に作成することもできます)。

詳細はこちら:.NETの世界のロギングファサードはありますか?

于 2012-04-24T22:22:14.733 に答える
0

ロギングラッパーをどの程度洗練させたいかによって異なりますか?

ロギングには複数のレベルがあり、情報と例外が標準です。

インターフェイスの使用を中心に展開する答えは100%正しいですが、DRY(Do n't Repeat Yourself)の原則もあります。

私の場合のように、コードが非常に反復的に見える場合は、インジェクションやインターフェイスなどの標準を使用することに加えて、エラーの処理にジェネリックラッパーを実装することもできます。

ジェネリックスを使用すると、ソリューションのロジックを分離して再利用できます。インターフェイスを使用すると、ロギングの概念を物理的な実装から切り離すことができます。

  public static output ExecuteBlockwithLogging<output, input, config>(ExeBlock<output, input, config> exeBlock, input InputForExeBlock, ILoggingBlock logger)
    {

        exeBlock.Execute(InputForExeBlock);

        if ((exeBlock.logEntries != null) && (exeBlock.logEntries.Length > 0))
        {
            logger.Execute(exeBlock.logEntries);
        }


        if ((exeBlock.exceptions != null) && (exeBlock.exceptions.Length > 0))
        {
            foreach (var e in exeBlock.exceptions)
            {

                var dictionaryData = new Dictionary<string, string>();
                if (e.Data.Count > 0)
                {
                    foreach (DictionaryEntry d in e.Data)
                    {
                        dictionaryData.Add(d.Key.ToString(), d.Value.ToString());
                    }
                }

                var messages = e.FromHierarchy(ex => ex.InnerException).Select(ex => ex.Message);


                LoggingEntry LE = new LoggingEntry
                {
                    description = e.Message,
                    exceptionMessage = String.Join(Environment.NewLine, messages),
                    source = exeBlock.GetType().Name,
                    data = dictionaryData
                };

                logger.Execute(new LoggingEntry[] { LE });
            }
            return default(output);
        }

        return exeBlock.Result;
    }
于 2017-09-06T08:24:23.170 に答える