2015-02-10 65 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