2013-07-23 85 views
5

我一直在玩AOP多年,但沒有成爲100%滿意的解決方案。 AOP帶有運行時編織的框架(如Spring.AOP)不能更改類的接口。 隨着後編譯時間框架像Postsharp(任何人都知道別人?)你可以。 檢查此示例,它將INotifyPropertyChanged實現添加到您的類中。 - >http://www.postsharp.net/model/inotifypropertychangedAOP預編譯時間編織?

這AOP功能真的很棒,但你在煩惱很快跑...... 如果你想託管組件內訪問新的界面,你不能編譯, 因爲接口編譯後添加。 所以你得到一個「PropertyChanged沒有定義」 - 錯誤。 因此,您必須將這個類分爲另一個程序集,這樣才能使用這些AOP優勢。 我記得,我遇到了同樣的「後編譯時間」 - 使用T4模板生成源代碼,基於程序集的反映信息。 OK,所以後期編譯時間有時候太晚了......

我在找的是一個解決方案,其中類的源代碼是通過Visual Studio用戶定義的工具解析的,然後在C#中生成代碼,文件,在部分類中。 (所以所有的AOP應用類必須是部分)

所以它是一種「預編譯時間AOP」。 這應該是明確可能的,並且可以通過使用NRefactory作爲代碼解析器來完成。 此外,Visual Studio會比這個後期編譯修改更喜歡這個。

所以這個解決方案消除了編譯後編織器的缺點。 但並不能給你AOP的所有功能。但是與AOP-Framework一起,這應該是令人厭惡的。

有沒有人知道這樣的框架,或討論? 你覺得呢?

親切的問候,托馬斯

回答

0

在PostSharp的情況下,可以利用該方法Post.Cast,這是一種轉換操作符的,在編譯後驗證訪問在編譯時間後推出的接口-時間。有關文檔,請參閱http://doc.postsharp.net/postsharp-3.0/Content.aspx/PostSharp-3.0.chm/html/M_PostSharp_Post_Cast__2.htm

+0

謝謝,恕我直言,這是對架構的影響,因爲您在代碼中添加了複雜性(= cast)。這是你問Anders Hejlsberg「打開編譯器?」的一個要點嗎? Quote:「來自代碼合同的人可能會讚賞鉤住編譯器的能力,這種需求在很大程度上被忽略了。」來源:http://www.postsharp.net/blog/post/Anders-Hejlsberg-Dead-Body –

1

因爲我和你已經在使用SNAP作爲一個可行的替代方案相對應,我想我會在這裏發佈我們的討論摘要,以幫助那些正在尋找類似解決方案的人。

總之,SNAP提供了一個運行時AOP框架,不會以任何方式更改您的代碼。沒有後期編譯步驟,只是運行時攔截,這是可預測和易於使用的。

+0

謝謝你,我認爲靜態編織和運行時DI都是很好的工具。我個人更喜歡靜態編織,因爲它對建築的影響較小。當然,使用DI你可以更好地控制你的方面。但祝賀SNAp,你做了一個偉大的項目:) –

1

你在找什麼是pMixins。它仍處於測試階段,但它完全符合您的需求:設計時編織。 AOP代碼生成爲部分代碼隱藏類,因此可在設計時使用。

因此,這意味着,你可以在一個文件中做到這一點,編譯器是幸福的,Visual Studio是幸福,ReSharper的是高興:

定義一個接口:

public interface ISomeInterface 
{ 
    void SomeMethod(); 
} 

創建接口的實現(我稱之爲一個mixin):

public class SomeInterfaceImplementation : ISomeInterface 
{ 
    public void SomeMethod() 
    { 
     //implementation 
    } 
} 

定義目標文件(這將消耗的Mixin):

[pMixin(Mixin = typeof(SomeInterfaceImplementation))] 
public partial class Target { } 

讓我們創建一個實用工具類,與SomeInterfaceSomeInterfaceImplementation工作原理:因爲只要你

class Program 
{ 
    private static void Main(string[] args) 
    { 
     //Call the mixed in method 
     new Target().SomeMethod(); 

     //Target implements ISomeInterface is code-behind 
     new Utility().DoSomeWorkOnSomeInterface(new Target()); 

     //Target has an implicit conversion operator to 
     //SomeInterfaceImplementation in code-behind 
     new Utility().DoSomeWorkOnImplementation(new Target()); 
    } 
} 

這部作品的原因是:

public class Utility 
{ 
    public void DoSomeWorkOnSomeInterface(ISomeInterface obj) 
    { 
     obj.SomeMethod(); 
    } 

    public void DoSomeWorkOnImplementation(SomeInterfaceImplementation obj) 
    { 
     obj.SomeMethod(); 
    } 
} 

現在讓我們來看看它的所有一起工作保存文件,pMixins代碼生成器立即進行設計時編織並更新代碼隱藏文件。它將SomeMethod直接添加到Target,更新Target的類定義以實現ISomeInterface並創建轉換運算符。

披露:我在pMixins開發團隊。

+0

順便說一句@ Gael-Fraiteur - PostSharp是一款出色的工具,它讓我在C#中變成了AOP! –

+0

@Thomas Haller - 你的建議完全正確,可以使用NRefactory完成。這正是我使用的! –