5

我和 AOP 一起玩了很多年,但对解决方案并没有 100% 满意。具有运行时编织的 AOP 框架,如 Spring.AOP,不能更改类的接口。使用 Postsharp 之类的后编译时框架(有人认识其他人吗?),您可以。查看此示例,它将 INotifyPropertyChanged 实现添加到您的类中。-> http://www.postsharp.net/model/inotifypropertychanged

这个 AOP 特性确实很棒,但是你很快就会遇到麻烦……如果你想访问宿主程序集中的新接口,你不能编译,因为接口是在编译后添加的。所以你得到一个“未定义PropertyChanged”-错误。因此,您必须通过将类分离到另一个程序集中来解决这个问题,这样您就可以利用这些 AOP 优势。我记得,我遇到了相同的“后编译时间”——使用基于程序集的反射信息生成源代码的 T4 模板的问题。好的,所以后编译时间有时为时已晚......

我正在寻找的是一种解决方案,其中类的源代码通过 Visual Studio 用户定义的工具进行解析,然后在 C# 文件中的部分类中生成代码。(所以所有 AOP 应用的类都必须是部分的)

所以它是一种“预编译时AOP”。这绝对是可能的,并且可以通过使用 NRefactory 作为代码解析器来完成。此外,Visual Studio 更希望这样,而不是编译后修改。

所以这个解决方案消除了编译后编织器的缺点。但不会为您提供 AOP 的所有功能。但是与 AOP-Framework 一起使用,这应该很不错。

有谁知道这样的框架,或者讨论?!你怎么看 ?

亲切的问候,托马斯

4

3 回答 3

1

由于您和我已经就使用SNAP作为可行的替代方案进行了相应的沟通,因此我想我会在此处发布我们讨论的摘要,以使那些正在寻找类似解决方案的人受益。

简而言之,SNAP提供了一个运行时 AOP 框架,它不会以任何方式更改您的代码。没有后编译步骤,只有运行时拦截,可预测且易于使用。

于 2013-08-09T14:59:26.400 回答
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 { }

SomeInterface让我们创建一个与and一起使用的实用程序类SomeInterfaceImplementation

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

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

现在让我们看看它们一起工作:

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());
    }
}

这样做的原因是,一旦您保存文件,pMixins 代码生成器就会立即进行设计时编织并更新代码隐藏文件。它将SomeMethod直接添加到Target, 更新Target的类定义以实现ISomeInterface并创建转换运算符。

披露:我在 pMixins 开发团队。

于 2014-07-09T17:44:45.167 回答
0

在 PostSharp 的情况下,您可以使用 method 访问在编译后引入的接口Post.Cast,这是一种在编译后验证的强制转换运算符。有关文档,请参阅http://doc.postsharp.net/postsharp-3.0/Content.aspx/PostSharp-3.0.chm/html/M_PostSharp_Post_Cast__2.htm

于 2013-07-23T11:58:10.017 回答