面向方面的设计模式布谷鸟&x27;使用PostSharp在C#中添加鸡蛋
我正在尝试使用Postsharp在C#中实现AO设计模式布谷鸟蛋 这种设计模式的思想正如其名称所述,是用其他对象替换现有对象。在AspectJ中,它是通过以下方式完成的:面向方面的设计模式布谷鸟&x27;使用PostSharp在C#中添加鸡蛋,c#,design-patterns,postsharp,aop,C#,Design Patterns,Postsharp,Aop,我正在尝试使用Postsharp在C#中实现AO设计模式布谷鸟蛋 这种设计模式的思想正如其名称所述,是用其他对象替换现有对象。在AspectJ中,它是通过以下方式完成的: public aspect MyClassSwapper { public pointcut myConstructors(): call(MyClass.new()); Object around(): myConstructors() { return new AnotherClass(); } }
public aspect MyClassSwapper {
public pointcut myConstructors(): call(MyClass.new());
Object around(): myConstructors() {
return new AnotherClass();
}
}
public class AnotherClass extends MyClass {
. . .
}
[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());
}
}
}
[MyClassSwapper(typeof (AnotherClass))]
class MyClass
{
// ...
}
我是Postsharp的新手,所以我想问一下,Postsharp中是否有能够执行类似操作的工具—重写基类构造函数的返回值并返回子类的对象?虽然Postsharp允许您应用于构造函数,但您仍然无法替换返回的对象实例。事实上,C#中的构造函数不返回值。有相关的问题和建议
实现布谷鸟蛋模式的另一种方法是拦截原始类的方法,并在另一个类实例上调用适当的方法。在这种情况下,另一个类
甚至不必从MyClass
派生,或者您可以将不同的方法委托给不同的替换类
实现模式的示例实现可以如下所示:
public aspect MyClassSwapper {
public pointcut myConstructors(): call(MyClass.new());
Object around(): myConstructors() {
return new AnotherClass();
}
}
public class AnotherClass extends MyClass {
. . .
}
[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());
}
}
}
[MyClassSwapper(typeof (AnotherClass))]
class MyClass
{
// ...
}
此实现需要从MyClass
派生另一个类MyClass
,并且必须在MyClass
本身上应用该属性,例如:
public aspect MyClassSwapper {
public pointcut myConstructors(): call(MyClass.new());
Object around(): myConstructors() {
return new AnotherClass();
}
}
public class AnotherClass extends MyClass {
. . .
}
[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());
}
}
}
[MyClassSwapper(typeof (AnotherClass))]
class MyClass
{
// ...
}