首页
/ MediatR中处理多个通知事件的通用模式

MediatR中处理多个通知事件的通用模式

2025-05-20 22:18:00作者:霍妲思

在MediatR项目中,开发者经常遇到需要处理多个类似通知事件的情况。本文探讨如何优雅地实现一个通用处理器来处理多个相关事件,避免代码重复。

问题背景

当使用MediatR处理领域事件时,经常会遇到多个事件需要执行相同或类似逻辑的场景。例如,在一个测试管理系统中,可能有TestResultRenamedTestResultTestCreatedTestResultTestCommentChanged等多种事件,它们都需要执行相同的后续处理逻辑。

传统做法是为每个事件类型单独实现一个处理器方法,导致大量重复代码:

public Task Handle(TestResultTestParameterAdded notification, CancellationToken cancellationToken)
    => HandleTestResultEvent(notification, cancellationToken);

public Task Handle(TestResultTestParameterRemoved notification, CancellationToken cancellationToken)
    => HandleTestResultEvent(notification, cancellationToken);

解决方案

1. 使用基类事件

最优雅的解决方案是让所有相关事件继承自一个公共基类,然后实现一个处理该基类的通用处理器:

// 定义基类事件
public abstract class TestResultEvent : INotification
{
    // 公共属性
}

// 具体事件继承基类
public class TestResultRenamed : TestResultEvent { /*...*/ }
public class TestResultTestCreated : TestResultEvent { /*...*/ }

// 通用处理器
public class TestResultContextSubscriber : INotificationHandler<TestResultEvent>
{
    public Task Handle(TestResultEvent notification, CancellationToken cancellationToken)
    {
        // 通用处理逻辑
        return HandleTestResultEvent(notification, cancellationToken);
    }
}

2. 注册服务

确保正确注册处理器服务:

services.AddScoped<INotificationHandler<TestResultEvent>, TestResultContextSubscriber>();

3. 工作原理

当发布任何继承自TestResultEvent的事件时,MediatR会自动调用这个通用处理器。同时,如果某些事件需要特殊处理,仍然可以保留它们特定的处理器。

注意事项

  1. 事件继承关系:确保所有需要通用处理的事件都正确继承自基类事件。

  2. 处理器优先级:MediatR会同时调用特定事件处理器和基类事件处理器,执行顺序取决于注册顺序。

  3. 性能考虑:这种模式不会带来额外性能开销,因为MediatR内部已经优化了通知分发机制。

  4. 异常处理:在通用处理器中实现统一的异常处理逻辑,可以简化错误处理流程。

高级用法

对于更复杂的场景,可以结合策略模式:

public class TestResultContextSubscriber : INotificationHandler<TestResultEvent>
{
    private readonly Dictionary<Type, Action<TestResultEvent>> _handlers;
    
    public TestResultContextSubscriber()
    {
        _handlers = new Dictionary<Type, Action<TestResultEvent>>
        {
            { typeof(TestResultRenamed), e => HandleRenamed((TestResultRenamed)e) },
            { typeof(TestResultTestCreated), e => HandleCreated((TestResultTestCreated)e) }
        };
    }
    
    public Task Handle(TestResultEvent notification, CancellationToken cancellationToken)
    {
        if(_handlers.TryGetValue(notification.GetType(), out var handler))
        {
            handler(notification);
        }
        else
        {
            // 默认处理逻辑
        }
        return Task.CompletedTask;
    }
}

这种模式在保持代码整洁的同时,提供了足够的灵活性来处理各种事件场景。

登录后查看全文
热门项目推荐
相关项目推荐