如何使用reflection将事件处理程序附加到事件?
我知道EventInfo.AddEventHandler(...)
方法,它可以用来将处理程序附加到事件。 但是,如果我甚至无法定义事件处理程序的正确签名,应该怎么做,因为我甚至没有引用处理程序所期望的事件args?
我将用正确的代码解释问题。
//当我在我的解决方案中提供一切可用的场景时,Zero Reflection Scenario。
internal class SendCommentsManager { public void Customize(IRFQWindowManager rfqWindowManager) { rfqWindowManager.SendComment += HandleRfqSendComment; } private void HandleRfqSendComment(object sender, SendCommentEventArgs args) { args.Cancel = true; } }
现在,我希望通过使用reflection来实现相同的目标。 我已经能够弄清楚它的大部分但是当我将一个委托附加到事件时(使用AddEventHandler
)它会抛出"Error binding to target method."
例外。
我理解这个exception背后的原因,将错误的委托附加到事件中。 但必须有一些方法来实现这一目标。
internal class SendCommentsManagerUsingReflection { public void Customize(IRFQWindowManager rfqWindowManager) { EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment"); eventInfo.AddEventHandler(rfqWindowManager, Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "HandleRfqSendComment")); //<<<<<<<<<>>>>>>>>>>>>> } private void HandleRfqSendComment(object sender, object args) { Type sendCommentArgsType = args.GetType(); PropertyInfo cancelProperty = sendCommentArgsType.GetProperty("Cancel"); cancelProperty.SetValue(args, true, null); } }
我认为你的代码失败了,因为HandleRfqSendComment
是私有的。 相反,您可以直接创建该方法的委托,而不将其名称传递给CreateDelegate
。 然后,您需要使用以下方法将委托转换为所需的类型:
public static Delegate ConvertDelegate(Delegate originalDelegate, Type targetDelegateType) { return Delegate.CreateDelegate( targetDelegateType, originalDelegate.Target, originalDelegate.Method); }
在您的代码中,您可以使用此方法,如下所示:
EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment"); Action
您可能需要考虑观察者模式: http : //www.dofactory.com/Patterns/PatternObserver.aspx