2015-02-10 36 views
1

據我所知,所有編譯時.NET面向方面編程框架(如PostSharp或Fody)只能處理已成功編譯的代碼。使用編譯時方面來實現抽象接口

這提出了一個障礙,如果你想使用這些框架的一個方面來實現的抽象接口的成員,因爲被修改的類將不執行生成後工序後,直到接口。如果由於缺少界面導致編譯階段失敗,則構建後步驟將無法運行。

例如,編寫一個WPF MVVM應用程序,我有一個抽象接口用於我的視圖模型。接口決定了視圖模型必須執行的命令,例如:

using System.Windows.Input 
public interface ITestVM 
{ 
    ICommand SomeCommand { get; } 
} 

我想創建一個具體的實現這個視圖模型抽象接口,使用Commander.Fody實現ICommand的實例。下面是我的嘗試:

using Commander; 
public class TestVM : ITestVM 
{ 
    [OnCommandCanExecute("SomeCommand")] 
    private bool SomeCommandCanExecute() 
    { 
    return true; 
    } 

    [OnCommand("SomeCommand")] 
    private void SomeCommandExecute() 
    { 
    } 
} 

這將產生「‘ITestVM.SomeCommand’TestVM「不實現接口成員」

我相信Commander.Fody 創建一個名爲一個ICommand實例錯誤信息一些命令,但它從來沒有機會這樣做。

有什麼辦法可以使用編譯時面向方面的框架來實現抽象接口嗎?我讀過「AOP.NET」這本書,編譯時編織章節中沒有討論這種限制(pp183-190)。

+0

你可以做的是有AOP框架注入整個界面而不只是執行。但是這可能會導致代碼中的其他問題,因爲您可能希望* TestVM執行ITestVM,並且編譯器會抱怨*。 – nvoigt 2015-02-10 19:51:50

+0

即使它沒有實現(在編譯時),也可以將一些對象轉換爲接口。所以你可以通過將TestVM投射到ITestVM來解決這個問題。 – 2015-02-13 07:54:12

回答

0

這是目前已知的工具,如PostSharp和Fody的限制,因爲它們是後編譯器編織器,而不是編譯時編織器。

要做到這一點的最好方法是實現一個屬性,您可以使用它作爲標記來指示類應該由織布工修改。然後在你的編織器中,你將不得不添加接口,並將實現添加到標記的類型中。

的PropertyChanged做了類似的事情與ImplementPropertyChangedAttribute

+0

好的。我可以看到這將是一個廣泛使用的接口(如INotifyPropertyChanged)的合理方法。在我的情況下,這是一個特定於類的接口(事實上,在實際使用中,我將遠遠超過一個命令),所以我認爲我會否定Commander.Fody的好處,如果每個命令都需要更多工作來實現比如果我手動掌握命令的話會更好。 – 2015-03-02 16:57:33

+0

我剛纔注意到,你提到了「後期編譯器」和「編譯時編織器」之間的區別。那是故意的嗎?從Groves的「.NET中的AOP」第7章中,我很熟悉運行時和編譯時編織之間的區別,但它將編譯時和編譯後時間視爲同義詞。如果還有另一類織布工更適合我描述的問題,我想了解它。 – 2015-03-02 20:10:13

+0

@TimCrews是的,我非常有意識地做出了區分。主要區別在於後編譯必須修改IL,而編譯時可以處理原始源代碼(C#/ VB/F#/ other)。異步狀態機是很難修改IL的例子,但是在編譯之前很容易修改代碼。 Try/Catch是另一件很難在IL級別操作的東西。 – 2015-03-03 01:15:40