关于C#:PostSharp-我编织-思想

关于C#:PostSharp-我编织-思想

PostSharp - il weaving - thoughts

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


我使用Castle Windsor DynamicProxies在AOP中应用日志记录。我已经在将Castle用于其IoC容器,因此将其用于AOP对我而言是最少保留的途径。如果您想了解更多信息,请告诉我,我正在整理代码以将其发布为博客文章。

编辑

好的,这是基本的拦截器代码,基本不行,但是可以完成我需要的一切。有两个拦截器,一个拦截器记录所有日志,另一个拦截器允许您定义方法名称,以实现更精细的日志记录。此解决方案有赖于温莎城堡

抽象基类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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;
        }
    }
}
}

完整日志记录

1
2
3
4
5
6
7
8
9
10
11
namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Logging;

public class LoggingInterceptor : AbstractLoggingInterceptor
{
    public LoggingInterceptor(ILoggerFactory logFactory) : base(logFactory)
    {
    }
}
}

方法记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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);
    }
}
}

postharp +1。已经使用了很多东西(包括尝试在C#代码中添加前置条件和后置条件),并且不知道如果没有它我该怎么做...


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

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

短期来看,没问题。


用它来做到这一点。很棒!我强烈推荐它!


推荐阅读