PostSharp-我编织-思想
时间:2020-03-06 14:20:48 来源:igfitidea点击:
我正在考虑使用Postsharp框架来减轻应用程序方法记录的负担。
基本上,它允许我装饰具有logging属性的方法,并在编译时将所需的日志代码注入il。我喜欢这种解决方案,因为它可以将噪声排除在设计时间代码环境之外。
有什么想法,经验或者更好的选择吗?
解决方案
我使用Castle Windsor DynamicProxies在AOP中应用日志记录。我已经将Castle用于其IoC容器,因此将其用于AOP对我而言是最少保留的途径。如果我们想了解更多信息,请告诉我,我正在整理代码以将其发布为博客文章。
编辑
好的,这是基本的拦截器代码,基本不行,但是可以完成我需要的一切。有两个拦截器,一个拦截器每一个都记录日志,另一个允许我们定义方法名称以允许进行更细粒度的日志记录。此解决方案有赖于温莎城堡
抽象基类
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); } } }
用它来做到这一点。很棒!我强烈推荐它!
postharp +1. 已经使用了很多东西(包括尝试在Ccode中添加前置条件和后置条件),并且不知道如果没有它我该怎么做...
这在一定程度上取决于我们将开发和支持该项目的时间。当然,IL编织是一项很好的技术,但是如果IL和/或者程序集元数据格式再次更改(如在1.1和2.0之间进行更改)并且这些更改使该工具与新格式不兼容,将会发生什么。
如果我们依赖该工具,那么它将阻止我们升级技术,直到该工具支持为止。由于没有任何保证(甚至可能继续发展,尽管看起来确实有可能),所以我会非常警惕在长期项目中使用它。
短期来看,没问题。