Recently I had a situation where I needed to test a class with dozens of event handlers. Rather than manually write the repetitive code to attach the handlers I decided to cheat and use reflection. Since there wasn’t anything immediately available online that I could find, I’m sharing an example here to show how to do it.
The code below is a simple console application that demonstrates this technique. There is a class ThingWithEvents that exports a couple of events, OnSayHello and OnCounter. The program creates an instance of this class then calls SubscribeToEvents. This reflects over all the events in the given type and for each event calls GetHandlerFor which generates an EventHandler<T> delegate of the correct type.
There’s a GitHub Gist here for any suggestions or comments.
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;
}