2013-07-23 170 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完成。这正是我使用的! –