PostSharp - il weaving - 想法

时间:2008-09-18 11:05:05

标签: c# visual-studio logging aop postsharp

我正在考虑使用Postsharp框架来减轻应用程序方法日志记录的负担。 它基本上允许我用日志属性装饰方法,并在编译时将所需的日志代码注入到il中。我喜欢这个解决方案,因为它可以将噪音排除在设计时代码环境之外。 任何想法,经验或更好的选择?

4 个答案:

答案 0 :(得分:7)

我使用Castle Windsor DynamicProxies在AOP上应用日志记录。我已经在使用Castle作为它的IoC容器了,所以将它用于AOP是我最不耐用的道路。如果您想了解更多信息请告诉我,我正在整理代码以将其作为博客文章发布

修改

好的,这是基本的Intercepter代码,非常基本,但它可以完成我需要的一切。有两个拦截器,一个记录每个记录,另一个允许您定义方法名称以允许更细粒度的记录。这个解决方案依赖于Castle Windsor

抽象基类

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 :(得分:6)

在postharp上

+1。一直在使用几件事(包括为C#代码添加前置条件和后置条件的一些尝试)并且不知道如果没有它我将如何制作它...

答案 2 :(得分:5)

这取决于你将为项目开发和支持多长时间。当然,IL编织是一项很好的技术,但是如果IL和/或程序集元数据格式再次发生变化(如1.1和2.0之间的情况)会发生什么,这些变化会使该工具与新格式不兼容。

如果您依赖该工具,那么它会阻止您升级您的技术,直到该工具支持它。由于没有任何保证(或者甚至开发将继续,尽管看起来很可能),所以我对在长期项目中使用它非常谨慎。

短期内,没问题。

答案 3 :(得分:3)

使用它来做到这一点。效果很好!我强烈推荐它!