1

リフレクションを介してイベントを発生させることが信頼できない理由について、あちこちで多くの投稿を読んでいます..私の問題はこれです..私はPostSharpを使用して、プロパティが変更される前後にクラスが通知できるようにするインターフェイスを定義しています..

作成されたNotifyAttributeive は、イベントを発生させることができる必要がPropertyBeforeChangeありPropertAfterChangeます..イベントを取得できても、GetRaiseMethod()null が返されるため、上記のイベントを発生させることができません..どうすればそれを行うことができますか?

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)
    {
    }
4

0 に答える 0