【问题标题】:consuming stored events via several consumers and event handlers通过多个消费者和事件处理程序使用存储的事件
【发布时间】:2016-02-04 09:00:38
【问题描述】:

我目前正在使用这种模式来处理来自某个事件接收器(例如企业服务总线、队列、EventStore)的事件。这个想法是在一个列表中实例化几个 IEventWorker(参见下面的具体示例)并传递事件,例如,通过调用每个实例的 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 将如何工作以分发来自例如事件队列的所有事件。

【问题讨论】:

    标签: c# events reactivex


    【解决方案1】:

    您的问题性质相当广泛;也许有点太多了。我鼓励你改进它。

    但是,您要求潜在的改进,我至少可以想到一件足够具体的事情:

    • 为了类型安全,您可以使用双重调度而不是类型转换。

    请参阅the visitor pattern 了解更多信息。在您的情况下,您将在IEvent 上创建一个类似Accept 的方法并在HandleEvent 中调用它:

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

    事件类型的接受方法如下所示:

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

    (虽然这当然仍然是一个虚拟调用,但请注意处理程序方法重载现在是静态选择的。这与您现有的运行时字典查找形成对比。)

    IEventWorker 接口将要求每个事件类型有一个方法,这相当于“注册”它们,尽管这次是以类型安全的方式。请注意,这会改变他们在您的实现中的访问级别,这很好。

    然后您可以完全删除映射字典;你现在使用类的虚拟表来达到同样的效果。

    我不会继续声称性能改进(如果它在您的场景中很重要),但如果它很重要,您可能需要测试并查看(您至少应该期望更好的性能)。

    【讨论】:

      猜你喜欢
      • 2020-04-21
      • 2012-11-21
      • 1970-01-01
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      相关资源
      最近更新 更多