Search code examples
c#reflectionevent-handlinginternals

How can I subscribe to an internal static event Action with reflection?


I want to subscribe a delegate to an external class' internal event Action:

internal static event Action OnSingletonReady;

I cannot edit the class it is in. Although the event may be exposed as public in the future, I can't wait for that to happen.

What is necessary to add/remove delegates from an internal action?


Solution

  • I believe that setting the nonPublic argument when you reflect the add method using GetAddMethod would have the desired outcome, at least it did when I tested it.

    using System.Reflection;
    
    Console.Title = "Subscribe to Internal Event";
    var action = typeof(ReflectionTestClass)
        .GetEvent(nameof(ReflectionTestClass.OnSingletonReady), BindingFlags.Static | BindingFlags.NonPublic);
    
    var methodInfo =
        action?
        .GetAddMethod(nonPublic: true);
    
        // Subscribe to the action 
        methodInfo?.Invoke(action, new object[] { ()=>
        {        
            Console.WriteLine($@"[{DateTime.Now:hh\:mm\:ss\:fff}] Event received.");
        } } );
    
    Console.WriteLine($@"[{DateTime.Now:hh\:mm\:ss\:fff}]");
    await Task.Delay(1000);
    _ = ReflectionTestClass.Get();
    
    Console.ReadKey();
    
    class ReflectionTestClass
    {
        private ReflectionTestClass() { }
        public static ReflectionTestClass Get()
        {
            if(_singleton is null)
            {
                _singleton = new ReflectionTestClass();
                OnSingletonReady?.Invoke();
            }
            return _singleton;
        }
        private static ReflectionTestClass? _singleton = null;
        internal static event Action? OnSingletonReady;
    }
    

    console output