AddEventHandler using reflection
I have this piece of code that does not work:
public CartaoCidadao()
{
InitializeComponent();
object o = WebDAV.Classes.SCWatcher.LoadAssembly();
MethodInfo method =
this.GetType().GetMethod("Inserted",
BindingFlags.NonPublic | BindingFlags.Instance);
EventInfo eventInfo = o.GetType().GetEvent("CardInserted");
Type type = eventInfo.EventHandlerType;
Delegate handler = Delegate.CreateDelegate(type, this , method);
eventInfo.AddEventHandler(o, handler);
}
void Inserted(string readerName, string cardName)
{
System.Windows.Forms.MessageBox.Show(readerName);
}
The Event CardInserted exists in another DLL file and object "o" loads OK. The delegate handler has a value after effect. I only can't fire the event.
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());
}
}
}
Here's a short but complete example which does work:
using System;
using System.Reflection;
class EventPublisher
{
public event EventHandler TestEvent;
public void RaiseEvent()
{
TestEvent(this, EventArgs.Empty);
}
}
class Test
{
void HandleEvent(object sender, EventArgs e)
{
Console.WriteLine("HandleEvent called");
}
static void Main()
{
// Find the handler method
Test test = new Test();
EventPublisher publisher = new EventPublisher();
MethodInfo method = typeof(Test).GetMethod
("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance);
// Subscribe to the event
EventInfo eventInfo = typeof(EventPublisher).GetEvent("TestEvent");
Type type = eventInfo.EventHandlerType;
Delegate handler = Delegate.CreateDelegate(type, test, method);
// Raise the event
eventInfo.AddEventHandler(publisher, handler);
publisher.RaiseEvent();
}
}
Now, when you say "I only can't fire event", what exactly do you mean? You're not meant to be able to raise events yourself - it's up to the event publisher to do that. Does all of the code you've actually presented to us work? If so, it seems that it's not adding the event handler that's the problem.
Could you give more information?
When you say it doesn't work... what happens? Nothing? An exception?
Thoughts:
- are both the event and the handler public? If not, you'll need to pass suitable
BindingFlags
to theGetEvent
/GetMethod
calls. - does the signature of the handler match?
Here's a working example (note I'm using a static handler, hence the null in Delegate.CreateDelegate
):
using System;
using System.Reflection;
class Test
{
public event EventHandler SomeEvent;
public void OnSomeEvent()
{
if (SomeEvent != null) SomeEvent(this, EventArgs.Empty);
}
static void Main()
{
Test obj = new Test();
EventInfo evt = obj.GetType().GetEvent("SomeEvent");
MethodInfo handler = typeof(Test)
.GetMethod("MyHandler");
Delegate del = Delegate.CreateDelegate(
evt.EventHandlerType, null, handler);
evt.AddEventHandler(obj, del);
obj.OnSomeEvent();
}
public static void MyHandler(object sender, EventArgs args)
{
Console.WriteLine("hi");
}
}