2008-09-18 21 views
10

我正在考慮使用Postsharp框架來減輕應用程序方法日誌的負擔。 它基本上允許我用日誌記錄屬性來裝飾方法,並在編譯時將需要的日誌代碼注入到日誌中。我喜歡這個解決方案,因爲它可以將噪音排除在設計時間碼環境之外。 任何想法,經驗或更好的選擇?PostSharp - il weaving - 思想

+0

我在想同樣的事情。很想聽聽人們的想法。 – 2008-09-18 11:07:30

+0

對我來說好幾個星期了 - 但我認爲編譯時的開銷非常值得缺乏日誌代碼,如果有人使用它,非常棒。 – redsquare 2008-09-18 11:09:14

回答

7

我使用Castle Windsor DynamicProxies應用AOP日誌記錄。我已經使用Castle作爲它的IoC容器,因此將它用於AOP是我的最小阻力路徑。如果您想了解更多的信息讓我知道,我在整理代碼的過程中我了釋放它作爲一個博客帖子

編輯

好吧,這裏的基本截擊代碼,faily基本的,但它做的一切我需要。有兩個攔截器,一個是日誌記錄,另一個允許您定義方法名稱以允許更細粒度的記錄。該解決方案是faily依賴於溫莎城堡

抽象基類

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; 
     } 
    } 
} 
} 

完整的日誌記錄Implemnetation

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); 
    } 
} 
} 
+0

嗨如果你可以給一個快速演示 - 它是否可以通過方法上的屬性工作 – redsquare 2008-09-18 11:12:46

+0

我並不熱衷於使用Attribute來處理橫切會議記錄,驗證等。我使用基於Boo的外部DSL用於配置IoC容器,並在那裏分配日誌記錄。這意味着我可以添加/刪除日誌記錄,而無需編寫C# – 2008-09-18 11:17:09

3

已經用它來做到這一點。很棒!我強烈推薦它!

6

+1在postsharp上。已經使用了幾件事情(包括一些嘗試向C#代碼添加先決條件和後置條件),並不知道如何在沒有它的情況下做出這種嘗試......

5

這取決於你在多長時間內正在開發和支持該項目。當然,IL編織是一項很好的技術,但是如果IL和/或彙編元數據格式再次發生變化(如1.1和2.0之間),那麼會發生什麼情況,並且這些變化會使工具與新格式不兼容。

如果您依賴該工具,那麼它會阻止您升級您的技術,直到該工具支持該技術。由於沒有關於這方面的保證(或者即使這種發展會繼續下去,雖然看起來很可能),但我仍然非常謹慎地將其用於長期項目。

短期,沒問題。