Addeventhandler Using Reflection

AddEventHandler using reflection

Here's a sample showing how to attach an event using reflection:

class Program
{
static void Main(string[] args)
{
var p = new Program();
var eventInfo = p.GetType().GetEvent("TestEvent");
var methodInfo = p.GetType().GetMethod("TestMethod");
Delegate handler =
Delegate.CreateDelegate(eventInfo.EventHandlerType,
p,
methodInfo);
eventInfo.AddEventHandler(p, handler);

p.Test();
}

public event Func<string> TestEvent;

public string TestMethod()
{
return "Hello World";
}

public void Test()
{
if (TestEvent != null)
{
Console.WriteLine(TestEvent());
}
}
}

Add Event Handler using Reflection ? / Get object of type?

Basically, what you have is fine. The only glitch is that myhandler actually needs to be of the correct type, which is to say: of the type defined by the event.

For example:

using System;
using System.Collections.Specialized;
using System.Reflection;

class Program
{
static void Main()
{
Type AType = typeof(Foo);
var ObjectOfAType = new Foo();

Delegate myhandler = (NotifyCollectionChangedEventHandler)SomeHandler;
EventInfo info = AType.GetEvent("CollectionChanged");
info.AddEventHandler(ObjectOfAType, myhandler);

// prove it works
ObjectOfAType.OnCollectionChanged();
}

private static void SomeHandler(object sender, NotifyCollectionChangedEventArgs e)
=> Console.WriteLine("Handler invoked");
}
public class Foo
{
public void OnCollectionChanged() => CollectionChanged?.Invoke(this, null);
public event NotifyCollectionChangedEventHandler CollectionChanged;
}

There is a Delegate.CreateDelegate() method that takes a delegate type, an object instance, and a MethodInfo method; you can use this (using the event-type from EventInfo info) to create an appropriate delegate instance for a given method on a particular object.

How to attach event handler to an event using reflection?

I think your code is failing because the HandleRfqSendComment is private. Instead you could directly create a delegate to that method, without passing its name to CreateDelegate. You would then need to convert the delegate to the required type, using the following method :

public static Delegate ConvertDelegate(Delegate originalDelegate, Type targetDelegateType)
{
return Delegate.CreateDelegate(
targetDelegateType,
originalDelegate.Target,
originalDelegate.Method);
}

In your code, you could use this method as follows :

EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment");
Action<object, object> handler = HandleRfqSendComment;
Delegate convertedHandler = ConvertDelegate(handler, eventInfo.EventHandlerType);
eventInfo.AddEventHandler(rfqWindowManager, convertedHandler);

Add and remove async event handlers using reflection in c#

This should work:

var obj = new InstrumentInstance("foo");

EventCompletedHandler handler = async (s, e) => await ProcessInstrumentEvent(s, e);

foreach (var evt in obj.GetType().GetEvents(BindingFlags.Public | BindingFlags.Instance))
{
if (evt.EventHandlerType == typeof(EventCompletedHandler))
{
Console.WriteLine($"Binding '{evt.Name}'");
evt.AddEventHandler(obj, handler);
}
}

It should also work without the extra indirection:

EventCompletedHandler handler = ProcessInstrumentEvent;

Add and remove event handler via reflection c#

I think it's because you are creating a new handler each time: (which doesn't match the previous handler, so can't be removed from the invocation list)

public static void RemoveEventHandler(EventInfo eventInfo,
object item, Action action)
{
var parameters = GetParameters(eventInfo);
var handler = GetHandler(eventInfo, action, parameters); // <--
eventInfo.RemoveEventHandler(item, handler);
}

Why are you wrapping the Action? To lose the parameters? It is not possible to add/remove the eventInfo.RemoveEventHandler(item, action); because of the parameters. If you want to remove a newly generated handler, you should return that handler when you want to remove it.

public static Delegate AddEventHandler(EventInfo eventInfo, object item, Action action)
{
var parameters = GetParameters(eventInfo);
var handler = GetHandler(eventInfo, action, parameters);
eventInfo.AddEventHandler(item, handler);
return handler;
}

public static void RemoveEventHandler(EventInfo eventInfo,
object item, Delegate handler)
{
eventInfo.RemoveEventHandler(item, handler);
}

var handler = EventSubscriber.AddEventHandler(eventInfo, timer, TimerElapsed);

EventSubscriber.RemoveEventHandler(eventInfo, timer, handler);

How to add an event handler using reflection when do not have access to EventArgs type?

Actually, I figured it out.

I changed

var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), myArgsType });

to

var method = new DynamicMethod("MyHandlerImpl", null, new[] { typeof(object), typeof(EventArgs) });

and made the Program class public and everything worked.



Related Topics



Leave a reply



Submit