2014-01-25 2 views
2

Я зарегистрировал множество типов, реализующих интерфейс IEventListener<T>.Получите все типы, реализующие общий интерфейс, используя переменную типа с Autofac

Как разрешить все типы, которые реализуют IEventListener<T>, но используя только переменную типа?

Например, у меня есть событие SomethingHappened и два типа, которые реализуют интерфейс IEventListener<SomethingHappened>.

Я отправляю событие через некоторый EventBus, и я получаю его как экземпляр класса Object. Как я могу разрешить все слушатели (типы, реализующие интерфейс IEventListener<SomethingHappened>), используя только результат метода GetType()?

ответ

0

Есть несколько способов сделать это:

  1. Resolve слушателей по интерфейсу.
    Вы можете определить интерфейс вам от его общего определения:

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

    Тогда вы можете получить реализацию вам нужно от того, что вы хотите, от lifetimescope, например.

  2. Регистрация EventListeners по типу они слушают, шпоночное или Metadate регистрации, например

    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)); 
          } 
         } 
        } 
    } 
    

    Затем вы можете вводить все зарегистрированные обработчик событий, как

    IEnumerable<Lazy<IEventListener, EventListenerMetadata>> eventListeners 
    

    И получить слушатель событий вам нужно

    var listOfEventListeners = eventListeners.Where(x => x.Metadata.EventType == eventType); 
    
Смежные вопросы