我已经在这里和那里阅读了很多帖子,说明为什么通过反射提升事件是不可靠的..我的问题是这个..我使用PostSharp定义一个接口,允许类在属性之前和之后通知改变..
创建的NotifyAttribute
ive需要能够引发PropertyBeforeChange
和PropertAfterChange
事件..即使我可以检索事件,它的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)
{
}