2016-02-04 4 views
2

В настоящее время я использую этот шаблон для обработки событий, происходящих из какого-либо приемника событий (например, служебной шины предприятия, очереди, EventStore). Идея состоит в том, чтобы создать несколько экземпляров IEventWorkers (см. Конкретный пример ниже) в списке и передать события, например, путем вызова методов HandleEvent для каждого экземпляра во время циклирования по списку. Это базовый код бетона IEventWorkers:использование хранимых событий несколькими пользователями и обработчиками событий

public class EventWorker : IEventWorker 
{ 
    private Dictionary<Type, Action<object>> CreateEventHandlerMapping() 
    { 
     return new Dictionary<Type, Action<object>> 
     { 
     {typeof (Event1), o => Handle(o as Event1)}, 
     {typeof (Event2), o => Handle(o as Event2)}, 
     }; 
    } 

    private void Handle(Event1 eventToHandle) 
    { 

    } 

    private void Handle(Event2 eventToHandle) 
    { 

    } 

    public void HandleEvent(IEvent evt) 
    { 
     var eventType = evt.GetType(); 
     if (_eventHandlerMapping.ContainsKey(eventType)) 
     { 
     _eventHandlerMapping[eventType](evt); 
     } 
    } 
} 

Возможно, есть лучший способ сделать это?

PS:

This приходит довольно близко к тому, что я пытаюсь достичь. Я не совсем понимаю, как работает ObserverRegistry для распространения всех событий, например, из очереди событий.

ответ

1

Ваш вопрос довольно широк; возможно, слишком много. Я рекомендую вам доработать его.

Однако вы просите потенциальные улучшения, и я могу думать, по крайней мере, одну вещи достаточно специфической:

  • Вы можете использовать двойную отправку вместо типа литья для безопасности типов.

Для получения дополнительной информации см. the visitor pattern. В вашем случае, вы бы создать Accept -как метод на IEvent и назвать его в HandleEvent:

public void HandleEvent(IEvent evt) 
{ 
    evt.Accept(this); 
} 

Accept методы по типам событий будет выглядеть следующим образом:

public void Accept(IEventWorker worker) 
{ 
    worker.Handle(this); 
} 

(В то время как это все еще виртуальный Разумеется, обратите внимание, что перегрузка метода обработчика теперь выбрана статически. Это в отличие от существующего поиска в режиме реального времени.)

Интерфейс IEventWorker будет определять способ в соответствии с тип события, который является эквивалентом «регистрации» их, хотя на этот раз безопасным типом. Обратите внимание, что это изменит их уровень доступа на вашей реализации, и это нормально.

Вы можете полностью удалить словарь сопоставления; вы теперь используете виртуальную таблицу класса с тем же эффектом.

Я бы не стал настаивать на повышении производительности (если это даже имело значение в вашем сценарии), но если это важно, вы можете протестировать и посмотреть (вы должны хотя бы ожидать повышения производительности).

Смежные вопросы