Created
April 28, 2022 16:10
-
-
Save mikehadlow/3d7fdc986ef913c1d689dcbdecd7ae70 to your computer and use it in GitHub Desktop.
Attach Event Handlers By Reflection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace EventHandlersByReflection; | |
using System.Reflection; | |
using static System.Console; | |
public class Program | |
{ | |
public static void Main() | |
{ | |
var thing = new ThingWithEvents(); | |
SubscribeToEvents(thing); | |
thing.SayHello("Hello World!"); | |
thing.Count(); | |
thing.Count(); | |
} | |
private static void SubscribeToEvents<T>(T target) | |
{ | |
foreach(var @event in target.GetType().GetEvents()) | |
{ | |
var handler = GetHandlerFor(@event); | |
@event.AddEventHandler(target, handler); | |
WriteLine($"Subscribed to {@event.Name}"); | |
} | |
} | |
static MethodInfo? genericHandlerMethod = typeof(Program).GetMethod("Handler", BindingFlags.Static | BindingFlags.NonPublic); | |
private static Delegate GetHandlerFor(EventInfo eventInfo) | |
{ | |
var eventArgsType = eventInfo.EventHandlerType?.GetMethod("Invoke")?.GetParameters()[1]?.ParameterType; | |
if(eventArgsType is null) | |
{ | |
throw new ApplicationException("Couldn't get event args type from eventInfo."); | |
} | |
var handlerMethod = genericHandlerMethod?.MakeGenericMethod(eventArgsType); | |
if(handlerMethod is null) | |
{ | |
throw new ApplicationException("Couldn't get handlerMethod from genericHandlerMethod."); | |
} | |
return Delegate.CreateDelegate(typeof(EventHandler<>).MakeGenericType(eventArgsType), handlerMethod); | |
} | |
// zero refernces, but accessed via reflection. Do not delete! | |
private static void Handler<TArgs>(object? sender, TArgs args) | |
{ | |
if(args is SayHelloEventArgs sayHelloEventArgs) | |
{ | |
WriteLine($"SayHello said: {sayHelloEventArgs.Messsage}"); | |
} | |
if(args is CounterEventArgs counterEventArgs) | |
{ | |
WriteLine($"Counter is {counterEventArgs.Counter}"); | |
} | |
} | |
} | |
public class ThingWithEvents | |
{ | |
private int counter = 0; | |
public void SayHello(string message) | |
{ | |
OnSayHello(this, new SayHelloEventArgs { Messsage = message }); | |
} | |
public void Count() | |
{ | |
OnCounter(this, new CounterEventArgs { Counter = counter }); | |
counter++; | |
} | |
public event EventHandler<SayHelloEventArgs> OnSayHello; | |
public event EventHandler<CounterEventArgs> OnCounter; | |
} | |
public class SayHelloEventArgs : EventArgs | |
{ | |
public string Messsage { get; set; } = ""; | |
} | |
public class CounterEventArgs : EventArgs | |
{ | |
public int Counter { get; set; } = 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment