通过反思提升事件

时间:2013-01-10 22:41:25

标签: c# reflection

我已经在这里和那里阅读了很多帖子,说明为什么通过反射提升事件是不可靠的..我的问题是这个..我使用PostSharp定义一个接口,允许类在属性之前和之后通知改变..

创建的NotifyAttribute ive需要能够引发PropertyBeforeChangePropertAfterChange事件..即使我可以检索事件,它的GetRaiseMethod()返回因为我无法提出上述事件。我怎么能这样做呢?

using PostSharp.Aspects;

namespace Core
{
    public delegate void PropertyBeforeChangeEventHandler(object sender, string sPropertyName, object oCurrentValue, ref object oProposedValue, ref bool bCancel);
    public delegate void PropertyAfterChangeEventHandler(object sender, string sPropertyName, object oOldValue, object oNewValue);

    public interface INotify
    {
        event PropertyBeforeChangeEventHandler PropertBeforeChange;
        event PropertyAfterChangeEventHandler PropertyAfterChange;
    }

    [Serializable]
    public sealed class NotifyAttribute : LocationInterceptionAspect, IInstanceScopedAspect
    {
        bool _NotifyBefore { get; set; }
        bool _NotifyAfter { get; set; }

        public NotifyAttribute() { _NotifyAfter = true; }
        public NotifyAttribute(bool bNotifyBefore, bool bNotifyAfter) { _NotifyBefore = bNotifyBefore; _NotifyAfter = bNotifyAfter; }

        public override void OnSetValue(LocationInterceptionArgs args)
        {
            INotify oNotify = args.Instance as INotify;
            if (oNotify == null) return;

            object oCurrentValue = args.GetCurrentValue();
            object oProposedValue = args.Value;
            if (object.Equals(oCurrentValue, oProposedValue)) return;
            bool bCancel = false;

            if (_NotifyBefore)
            {
                var oObj = args.Instance.GetType().GetEvent("PropertyBeforeChange");
                // RAISE EVENT HERE
            }
            if (bCancel) return;

            args.Value = oProposedValue;
            args.ProceedSetValue();
            if (_NotifyAfter)
            {
                var oObj = args.Instance.GetType().GetEvent("PropertyAfterChange");
                // RAISE EVENT HERE
            }
        }

        public object CreateInstance(AdviceArgs adviceArgs) { return this.MemberwiseClone(); }
        public void RuntimeInitializeInstance() { }
    }
}

定义了这个接口和这个属性后,我可以按如下方式使用它。

    public class Test : INotify
    {
        public event PropertyBeforeChangeEventHandler PropertyBeforeChange;
        public event PropertyAfterChangeEventHandler PropertyAfterChange;

        [Notify]
        public string Name { get; set; }
    }

    Test oTest = new Test();
    oTest.PropertyBeforeChange += Test_PropertBeforeChange;
    oTest.PropertyAfterChange += Test_PropertyAfterChange;
    oTest.Name = "Asim";
    void Test_PropertBeforeChange(object sender, string sPropertyName, object oCurrentValue, ref object oProposedValue, ref bool bCancel)
    {
    }
    void Test_PropertyAfterChange(object sender, string sPropertyName, object oOldValue, object oNewValue)
    {
    }

0 个答案:

没有答案