Skip to content

Instantly share code, notes, and snippets.

@mikehadlow
Created April 28, 2022 16:10
Show Gist options
  • Save mikehadlow/3d7fdc986ef913c1d689dcbdecd7ae70 to your computer and use it in GitHub Desktop.
Save mikehadlow/3d7fdc986ef913c1d689dcbdecd7ae70 to your computer and use it in GitHub Desktop.
Attach Event Handlers By Reflection
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