アプリケーション メソッドのロギングの負担を軽減するために、Postsharp フレームワークを使用することを検討しています。基本的に、ロギング属性を使用してメソッドを修飾し、コンパイル時に必要なロギング コードを il.xml に挿入することができます。このソリューションは、deign タイム コード環境からノイズを排除するので気に入っています。考え、経験、またはより良い代替案はありますか?
3 に答える
Castle Windsor DynamicProxies を使用して、AOP でログを適用します。私はすでに IoC コンテナーに Castle を使用していたので、AOP に使用することは、私にとって抵抗が最も少ない方法でした。詳細情報が必要な場合はお知らせください。ブログ投稿としてリリースするためにコードを整理中です。
編集
OK、これが基本的な Intercepter コードです。基本的なものではありませんが、必要なものはすべて実行されます。2 つのインターセプターがあり、1 つはすべてをログに記録し、もう 1 つはメソッド名を定義して、よりきめ細かいロギングを可能にします。このソリューションはウィンザー城に依存しています
抽象基本クラス
namespace Tools.CastleWindsor.Interceptors
{
using System;
using System.Text;
using Castle.Core.Interceptor;
using Castle.Core.Logging;
public abstract class AbstractLoggingInterceptor : IInterceptor
{
protected readonly ILoggerFactory logFactory;
protected AbstractLoggingInterceptor(ILoggerFactory logFactory)
{
this.logFactory = logFactory;
}
public virtual void Intercept(IInvocation invocation)
{
ILogger logger = logFactory.Create(invocation.TargetType);
try
{
StringBuilder sb = null;
if (logger.IsDebugEnabled)
{
sb = new StringBuilder(invocation.TargetType.FullName).AppendFormat(".{0}(", invocation.Method);
for (int i = 0; i < invocation.Arguments.Length; i++)
{
if (i > 0)
sb.Append(", ");
sb.Append(invocation.Arguments[i]);
}
sb.Append(")");
logger.Debug(sb.ToString());
}
invocation.Proceed();
if (logger.IsDebugEnabled && invocation.ReturnValue != null)
{
logger.Debug("Result of " + sb + " is: " + invocation.ReturnValue);
}
}
catch (Exception e)
{
logger.Error(string.Empty, e);
throw;
}
}
}
}
完全なロギングの実装
namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Logging;
public class LoggingInterceptor : AbstractLoggingInterceptor
{
public LoggingInterceptor(ILoggerFactory logFactory) : base(logFactory)
{
}
}
}
メソッドのロギング
namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Interceptor;
using Castle.Core.Logging;
using System.Linq;
public class MethodLoggingInterceptor : AbstractLoggingInterceptor
{
private readonly string[] methodNames;
public MethodLoggingInterceptor(string[] methodNames, ILoggerFactory logFactory) : base(logFactory)
{
this.methodNames = methodNames;
}
public override void Intercept(IInvocation invocation)
{
if ( methodNames.Contains(invocation.Method.Name) )
base.Intercept(invocation);
}
}
}
ポストシャープで+1。いくつかの目的(C#コードに前提条件と事後条件を追加する試みを含む)に使用してきましたが、それなしでどのように作成するかわかりません...
それは、プロジェクトの開発とサポートにどれだけの期間を費やすかによってある程度異なります。確かに、IL ウィービングは優れたテクノロジですが、IL および/またはアセンブリ メタデータの形式が (1.1 と 2.0 の間で行われたように) 再び変更され、それらの変更によってツールが新しい形式と互換性がなくなった場合はどうなるでしょうか。
ツールに依存している場合は、ツールがサポートするまでテクノロジをアップグレードできません。これについての保証がない場合 (または、その可能性が高いように見えますが、その開発が続くことさえあります)、長期的なプロジェクトで使用することには非常に注意を払う必要があります。
短期間ですが問題ありません。