如何动态应用方面?

时间:2014-10-19 13:57:26

标签: c# metaprogramming postsharp

我有这个词:

[NotifyPropertyChangedAspect] // my own aspect implementation...
class Foo {
    [OnSetAspect("OnSetExamplaryProperty")] // my own aspect implementation as well...
    public int ExamplaryProperty { get; set; }
    void OnSetExamplaryProperty() { /* do stuff... */ }

    public bool Condition { get; set; }

    [DependsOnAspect("Condition")]
    public bool Dependent { get; set; }
}

每当Condition发生变化时,我都希望PropertyChanged同时使用PropertyName == "Dependent"。我知道我可以反过来(在Condition上使用其依赖属性应用方面,或者只在构造函数中添加PropertyChanged处理程序),但我想这样: - )

以下是我能想到的可能的解决方案:

  1. 在编译过程中以某种方式注入我自己的OnSetAspect(覆盖CompileTimeInitialize?使用Emit?)
  2. 在运行时以某种方式注入我自己的OnSetAspect(再次,如何?)
  3. 使用OnSetAspect申请我自己的IAspectProvider(我猜这里......不太确定可行性和/或实施简单性)
  4. 那么如何填写我的DependsOnAspect班级团体来实现我的目标呢?

    [Serializable]
    public class DependsOnAspect : LocationInterceptionAspect {
        /* what goes here? */
    }
    

    什么是最简单的解决方案?

1 个答案:

答案 0 :(得分:1)

在我看来,您应截取set_Condition并在此处触发PropertyChanged事件。所以DependsOnAspect并不需要成为一个方面(你不需要变换Dependent,因为它具有属性) - 只是一个常规属性。

大纲是:NotifyPropertyChangedAspect将向所有属性设置者提供OnMethodBoundaryAspect s(它将实现IAspectProvider)并分析[DependsOn]属性的所有属性(在构建时) )。在运行时,每个属性setter方面将为PropertyChangedEvent属性指向特定属性的所有属性触发[DependsOn]

public class DependsOnAttribute : Attribute { ... }

[PSerializable]
[IntroduceInterface(typeof(INotifyPropertyChanged))]
public class NotifyPropertyChangedAspect : InstanceLevelAspect, IAspectProvider, INotifyPropertyChanged
{
    IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement)
    {
        // targetElement is Type, go through it's properties and provide SetterInterceptionAspect to them
    }

    public override void CompileTimeInitialize( Type type, AspectInfo aspectInfo )
    {
        // scan for [DependsOn] here
    }

    [PSerializable]
    public class SetterInterceptionAspect : OnMethodBoundaryAspect
    {
        // ...
        public override void OnExit(MethodExecutionArgs args)
        {
            // fire PropertyChanged event here
        }
        // ...
    }
    // ...
}

你需要稍微修补一下,但我希望这可以用作大纲。