我正在尝试使用Postsharp在C#中实现AO设计模式杜鹃蛋。

顾名思义,这种设计模式的思想是用其他对象替换现有对象。在AspectJ中,它是通过以下方式完成的:

public aspect MyClassSwapper {
  public pointcut myConstructors(): call(MyClass.new());
  Object around(): myConstructors() {
      return new AnotherClass();
  }
}

public class AnotherClass extends MyClass {
    . . .
}


我是Postsharp的新手,所以我想问一下,Postsharp中是否有一些工具可以执行类似的操作-覆盖基类的构造函数的返回值并返回子类的对象?

最佳答案

尽管PostSharp允许您将OnMethodBoundaryAspect应用于构造函数,但仍将无法替换返回的对象实例。实际上,C#中的构造函数不会返回值。有相关的问题herehere

实施杜鹃蛋模式的另一种方法是拦截原始类的方法,然后在另一个类实例上调用适当的方法。在这种情况下,AnotherClass甚至不必从MyClass派生,也可以将不同的方法委托给不同的替换类。

实现该模式的MethodInterceptionAspect的示例实现如下所示:

[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, Inheritance = MulticastInheritance.None)]
public class MyClassSwapperAttribute : MethodInterceptionAspect, IInstanceScopedAspect
{
    private readonly Type cuckooType;

    [NonSerialized] private object cuckooEgg;

    public MyClassSwapperAttribute(Type cuckooType)
    {
        this.cuckooType = cuckooType;
    }

    private MyClassSwapperAttribute()
    {
        // this creates an "empty" aspect instance applied on the cuckoo's egg itself
    }

    public object CreateInstance(AdviceArgs adviceArgs)
    {
        if (adviceArgs.Instance.GetType() == cuckooType)
            return new MyClassSwapperAttribute();

        return this.MemberwiseClone();
    }

    public void RuntimeInitializeInstance()
    {
        if (this.cuckooType == null)
            return;

        // for each instance of the target class we create a new cuckoo's egg instance
        this.cuckooEgg = Activator.CreateInstance(cuckooType);
    }

    public override void OnInvoke(MethodInterceptionArgs args)
    {
        if (this.cuckooEgg == null)
        {
            base.OnInvoke(args);
        }
        else
        {
            // delegate the method invocation to the cuckoo's egg, that derives from the target class
            args.ReturnValue = args.Method.Invoke(this.cuckooEgg, args.Arguments.ToArray());
        }
    }
}


此实现要求AnotherClassMyClass派生,并且您必须在MyClass本身上应用属性,例如:

[MyClassSwapper(typeof (AnotherClass))]
class MyClass
{
    // ...
}

关于c# - 使用PostSharp的C#中面向方面的设计模式杜鹃蛋,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20149344/

10-13 06:25