我正在尝试使用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#中的构造函数不会返回值。有相关的问题here和here。
实施杜鹃蛋模式的另一种方法是拦截原始类的方法,然后在另一个类实例上调用适当的方法。在这种情况下,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());
}
}
}
此实现要求
AnotherClass
从MyClass
派生,并且您必须在MyClass
本身上应用属性,例如:[MyClassSwapper(typeof (AnotherClass))]
class MyClass
{
// ...
}
关于c# - 使用PostSharp的C#中面向方面的设计模式杜鹃蛋,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20149344/