Log4Netラッパーインターフェースを作成しようとしています。インタフェースのためのコード:C#Reflection対メソッドの属性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PlayGround
{
public interface ILogger
{
void SetSource(string typeName);
/// <summary>
/// Provide Log "message" and/or "exception" data only
/// </summary>
/// <param name="message"></param>
/// <param name="exception"></param>
/// <param name="memberName"></param>
/// <param name="sourceFilePath"></param>
/// <param name="sourceLineNumber"></param>
void Error(string message, Exception exception = null,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = null,
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = null,
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
/// <summary>
/// Provide Log "message" and/or "exception" data only
/// </summary>
/// <param name="message"></param>
/// <param name="exception"></param>
/// <param name="memberName"></param>
/// <param name="sourceFilePath"></param>
/// <param name="sourceLineNumber"></param>
void Warn(string message, Exception exception = null,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = null,
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = null,
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
/// <summary>
/// Provide Log "message" and/or "exception" data only
/// </summary>
/// <param name="message"></param>
/// <param name="exception"></param>
/// <param name="memberName"></param>
/// <param name="sourceFilePath"></param>
/// <param name="sourceLineNumber"></param>
void Debug(string message, Exception exception = null,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = null,
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = null,
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
/// <summary>
/// Provide Log "message" and/or "exception" data only
/// </summary>
/// <param name="message"></param>
/// <param name="exception"></param>
/// <param name="memberName"></param>
/// <param name="sourceFilePath"></param>
/// <param name="sourceLineNumber"></param>
void Info(string message, Exception exception = null,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = null,
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = null,
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
/// <summary>
/// Provide Log "message" and/or "exception" data only
/// </summary>
/// <param name="message"></param>
/// <param name="exception"></param>
/// <param name="memberName"></param>
/// <param name="sourceFilePath"></param>
/// <param name="sourceLineNumber"></param>
void Fatal(string message, Exception exception = null,
[System.Runtime.CompilerServices.CallerMemberName] string memberName = null,
[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = null,
[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0);
}
}
実装:
using log4net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PlayGround
{
class Log4NetLogger : ILogger
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(Log4NetLogger));
private static readonly bool isErrorEnabled = log.IsErrorEnabled;
private static readonly bool isWarnEnabled = log.IsWarnEnabled;
private static readonly bool isDebugEnabled = log.IsDebugEnabled;
private static readonly bool isInfoEnabled = log.IsInfoEnabled;
private static readonly bool isFatalEnabled = log.IsFatalEnabled;
private string TypeName;
public void SetSource(string typeName)
{
TypeName = typeName;
}
public void Error(string message, Exception Exception = null, string memberName = null, string sourceFilePath = null, int sourceLineNumber = 0)
{
if (isErrorEnabled)
{
string Message = BuildSourceDetails(message, memberName, sourceFilePath, sourceLineNumber);
if (Exception != null)
{
Message += BuildExceptionMsg(Exception.Message);
}
log.Error(Message);
}
}
public void Warn(string message, Exception Exception = null, string memberName = null, string sourceFilePath = null, int sourceLineNumber = 0)
{
if (isWarnEnabled)
{
string Message = BuildSourceDetails(message, memberName, sourceFilePath, sourceLineNumber);
if (Exception != null)
{
Message += BuildExceptionMsg(Exception.Message);
}
log.Warn(Message);
}
}
public void Debug(string message, Exception Exception = null, string memberName = null, string sourceFilePath = null, int sourceLineNumber = 0)
{
if (isDebugEnabled)
{
string Message = BuildSourceDetails(message, memberName, sourceFilePath, sourceLineNumber);
if (Exception != null)
{
Message += BuildExceptionMsg(Exception.Message);
}
log.Debug(Message);
}
}
public void Info(string message, Exception Exception = null, string memberName = null, string sourceFilePath = null, int sourceLineNumber = 0)
{
if (isInfoEnabled)
{
string Message = BuildSourceDetails(message, memberName, sourceFilePath, sourceLineNumber);
if (Exception != null)
{
Message += BuildExceptionMsg(Exception.Message);
}
log.Info(Message);
}
}
public void Fatal(string message, Exception Exception = null, string memberName = null, string sourceFilePath = null, int sourceLineNumber = 0)
{
if (isFatalEnabled)
{
string Message = BuildSourceDetails(message, memberName, sourceFilePath, sourceLineNumber);
if (Exception != null)
{
Message += BuildExceptionMsg(Exception.Message);
}
log.Fatal(Message);
}
}
private string BuildSourceDetails(string message, string memberName, string sourceFilePath, int sourceLineNumber)
{
return "[Class: " + TypeName + " Member: " + memberName + " Source: " + sourceFilePath + " Line: " + sourceLineNumber + "] [" + message + "]";
}
private string BuildExceptionMsg(string message)
{
return " [System Exception: " + message + "] ";
}
}
}
私は、私が行ったオンライン調査に基づいてコードの動作性能の観点から考えています。
質問があります。インターフェイス内で属性を使用するのではなく、C#Reflectionを使用して具体的な実装にのみロギング用のコードを移動できる方法がありますか?この方法でインターフェイスはより一般的ですか?
ありがとうございました。
実際に何が必要なのかよく分かりません。しかし、あなたが必然的にリフレクションを使用する必要がある場合、スタックトレース(非常に遅い)は常に同じ情報を提供できます。 – leppie
@leppie:yesパフォーマンスに関する懸念があるため、stacktraceの使用を避けています。 – Guygar
呼び出しコードのNLogに直接依存したくないと思います。ファサードやアダプターのデザインパターンを使ってみませんか? –