我正在尝试使用 Postsharp 在C#中实现AO设计模式Cuckoo的蛋。
这种设计模式的概念就像它的名称状态一样,用其他对象替换现有对象。在 AspectJ 中,它由以下内容完成:
public aspect MyClassSwapper {
public pointcut myConstructors(): call(MyClass.new());
Object around(): myConstructors() {
return new AnotherClass();
}
}
public class AnotherClass extends MyClass {
. . .
}
我是Postsharp的新手所以我想问一下,如果Postsharp中有工具可以做类似的事情 - 覆盖基类构造函数的返回值并返回子类的对象?
答案 0 :(得分:0)
虽然 PostSharp 允许您将OnMethodBoundaryAspect应用于构造函数,但您仍然无法替换返回的对象实例。实际上,C#中的构造函数不返回值。相关问题here和here。
实现Cuckoo的egg模式的另一种方法是拦截原始类的方法,而是在另一个类实例上调用适当的方法。在这种情况下,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
{
// ...
}