3
votes

I have registered many types that implement IEventListener<T> interface.

How can I resolve all types that implement IEventListener<T> but using only Type variable ?

For example I have event SomethingHappened and two types that implement IEventListener<SomethingHappened> interface.

I'm sending event over some EventBus and I receiving it as instance of Object class. How can I resolve all listeners (types that implement IEventListener<SomethingHappened> interface) using only result of GetType() method ?

1

1 Answers

0
votes

There are a couple way to do it:

  1. Resolve listeners by interface.
    You can define the interface you need from its generic definition:

    var eventType = @event.GetType(); // suppose it's SomethingHappened type
    var eventListenerType = typeof(IEventListener<>).MakeGenericType(eventType);
    // eventListenerType is IEventListener<SomethingHappened>
    

    Then you can get the implementation you need from whatever you want, from lifetimescope for example.

  2. Register EventListeners by the type they listen, Keyed or Metadate registrations for example

    public static void RegisterMessageHandlers(this ContainerBuilder builder, params Assembly[] assemblies)
    {
        foreach (var assembly in assemblies)
        {
            var eventListeners = assembly.GetTypes().Where(
                t => t.IsClass &&
                     t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEventListener<>)));
    
            foreach (var eventListener in eventListeners)
            {
                var interfaces = eventListener.GetInterfaces().Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEventListener<>));
    
                foreach (var @interface in interfaces)
                {
                    var eventType = @interface.GetGenericArguments()[0];
                    builder.RegisterType(eventListener)
                        .As<IEventListener>()
                        .WithMetadata<EventListenerMetadata>(c => c.For(m => m.EventType, eventType));
                }
            }
        }
    }
    

    Then you can inject all registered event listeners as

    IEnumerable<Lazy<IEventListener, EventListenerMetadata>> eventListeners
    

    And get the event listener you need

    var listOfEventListeners = eventListeners.Where(x => x.Metadata.EventType == eventType);