2009-12-01 120 views
4

所以,我有這個問題,似乎沒有人能夠幫助。所以,不要一味抨擊,我會把它扔到那裏去尋找替代方法來給這隻特定的貓皮。AOP攔截屬性

目前,我有以下幾點:

public interface ICustomerService 
{ 
    Customer GetCustomer(int id); 
} 

public class CustomerService : ICustomerService 
{ 
    public Customer GetCustomer(int id) 
    { 
     ... 
    } 
} 

...與團結,我有國際奧委會的設置,並在同一時間配置的攔截,如:

IUnityContainer ioc = new UnityContainer(); 
ioc.RegisterType<ICustomerService, CustomerService>() 
    .Configure<Interception>() 
    .SetInterceptorFor<ICustomerService>(new InterfaceInterceptor()); 

什麼,我想才達到的以便能夠像這樣在界面中放置屬性:

public interface ICustomerService 
{ 
    [Log] 
    Customer GetCustomer(int id); 
} 

...定義爲:

public class LogAttribute: HandlerAttribute 
{ 
    public override ICallHandler CreateHandler(IUnityContainer container) 
    { 
     return new LogHandler(); 
    } 
} 

...然後在LogHandler類做的一切,我要像記錄:

public class LogHandler : ICallHandler 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     ... log stuff 
    } 
} 

我想要實現的是一個跟蹤/日誌系統中的處理程序日誌什麼的命名空間。正在調用class.methodname,並調用它的父名稱namespace.class.methodname。我試過沒有成功使用「輸入」IMethodInvocation參數來獲取我想要的信息,問題是,輸入返回「ICustomerService」接口,同時檢查父級的堆棧幀返回父級的實現類(例如。CustomerService)這意味着當我嘗試創建一個使用namespace.class.methodname作爲實體ID的樹結構時,ID和parentID不匹配。

將一個參數放入[Log]屬性不會真的起作用,因爲我可以在那裏放置什麼?如果我把接口名稱,我仍然有與上面相同的問題,其中一個接口的ID和父母是實施類。而且,我不能將實現類的名稱放在接口的屬性中,因爲這首先破壞了接口的用途!

所以,這是困境。任何人有新的想法?

回答

1

我結束了使用PostSharp來完成這樣的日誌記錄。 http://www.postsharp.org

+0

是的,我知道PostSharp的,但在我開始變得複雜的問題進一步與更多的dll的參考和工具,是PostSharp值得的,更重要的是,我想可能只使用Unity和Entlib? – krisg 2009-12-01 15:18:13

+1

我不知道只有Unity和Entlib是否可能。 我發現PostSharp的使用非常簡單,並且由於它是編譯時IL修改,所以不需要分發PostSharp程序集。 – user207462 2009-12-02 02:27:47

1

我使用Unity和攔截記錄工作。由於我缺乏配置設置技巧,我不得不通過編程來完成。您需要設置至少一個攔截器以及一個或多個策略對象。哦,是的,UnityContainer.Configure<Interception>是至關重要的。

有點像這樣:

// I'm using the TransparentProxyInterceptor because I want to trace EVERYTHING... 
var intp = myUnityContainer.Configure<Interception>(). 
    SetInterceptorFor(typeof(MyTypeToLog), new TransparentProxyInterceptor()); 

var policy = intp.AddPolicy("somePolicyName"); 

policy.AddMatchingRule<TypeMatchingRule>(
    new InjectionConstructor(
     new InjectionParameter(typeof(MyTypeToLog))) 
      .AddCallHandler(typeof(MyCallHandler), 
       new ContainerControlledLifetimeManager()); 

我當然需要定義攔截調用句柄,以及:

public class MyCallHandler : ICallHandler, IDisposable 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, 
     GetNextHandlerDelegate getNext) 
    { 
     var methodReturn = getNext().Invoke(input, getNext); 

     // log everything... 
     LogMethodCall(input, methodReturn); 

     // log exception if there is one... 
     if (methodReturn.Exception != null) 
     { 
      LogException(methodReturn); 
     } 

     return methodReturn; 
    } 
}