Skip to the content.

Mediator.Net

Stack Overflow 构建状态 CI Release codecov NuGet

一个强大而灵活的 .NET 中介者模式实现,通过解耦请求/响应处理来实现清洁架构。

Mediator.Net Logo

📋 目录

🚀 特性

📦 安装

通过 NuGet 安装主包:

Install-Package Mediator.Net

或通过 .NET CLI:

dotnet add package Mediator.Net

🏁 快速开始

基本设置

// 创建和配置中介者
var mediaBuilder = new MediatorBuilder();
var mediator = mediaBuilder.RegisterHandlers(typeof(Program).Assembly).Build();

定义消息和处理器

// 命令(无响应)
public class CreateUserCommand : ICommand
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public class CreateUserCommandHandler : ICommandHandler<CreateUserCommand>
{
    public async Task Handle(IReceiveContext<CreateUserCommand> context, CancellationToken cancellationToken)
    {
        // 处理命令
        var user = new User(context.Message.Name, context.Message.Email);
        // 保存用户...
        
        // 发布事件
        await context.Publish(new UserCreatedEvent { UserId = user.Id });
    }
}

// 请求/响应
public class GetUserQuery : IRequest<UserDto>
{
    public int UserId { get; set; }
}

public class GetUserQueryHandler : IRequestHandler<GetUserQuery, UserDto>
{
    public async Task<UserDto> Handle(IReceiveContext<GetUserQuery> context, CancellationToken cancellationToken)
    {
        // 处理查询并返回响应
        return new UserDto { Id = context.Message.UserId, Name = "张三" };
    }
}

// 事件
public class UserCreatedEvent : IEvent
{
    public int UserId { get; set; }
}

public class UserCreatedEventHandler : IEventHandler<UserCreatedEvent>
{
    public async Task Handle(IReceiveContext<UserCreatedEvent> context, CancellationToken cancellationToken)
    {
        // 处理事件
        Console.WriteLine($"用户 {context.Message.UserId} 已创建!");
    }
}

📋 使用示例

发送命令

// 无响应的命令
await mediator.SendAsync(new CreateUserCommand 
{ 
    Name = "张三", 
    Email = "zhangsan@example.com" 
});

// 有响应的命令
var result = await mediator.SendAsync<CreateUserCommand, CreateUserResponse>(
    new CreateUserCommand { Name = "李四", Email = "lisi@example.com" });

处理请求

// 有响应的请求
var user = await mediator.RequestAsync<GetUserQuery, UserDto>(
    new GetUserQuery { UserId = 123 });

发布事件

// 向所有处理器发布事件
await mediator.Publish(new UserCreatedEvent { UserId = 123 });

流式响应

创建返回多个响应的处理器:

public class GetMultipleUsersStreamHandler : IStreamRequestHandler<GetUsersQuery, UserDto>
{
    public async IAsyncEnumerable<UserDto> Handle(
        IReceiveContext<GetUsersQuery> context, 
        [EnumeratorCancellation] CancellationToken cancellationToken)
    {
        for (var i = 0; i < 10; i++)
        {
            await Task.Delay(100, cancellationToken);
            yield return new UserDto { Id = i, Name = $"用户 {i}" };
        }
    }
}

// 消费流
await foreach (var user in mediator.CreateStream<GetUsersQuery, UserDto>(new GetUsersQuery()))
{
    Console.WriteLine($"接收到:{user.Name}");
}

🔧 处理器注册

程序集扫描(推荐)

var mediator = new MediatorBuilder()
    .RegisterHandlers(typeof(Program).Assembly)
    .Build();

显式注册

var mediator = new MediatorBuilder()
    .RegisterHandlers(() => new List<MessageBinding>
    {
        new MessageBinding(typeof(CreateUserCommand), typeof(CreateUserCommandHandler)),
        new MessageBinding(typeof(GetUserQuery), typeof(GetUserQueryHandler)),
        new MessageBinding(typeof(UserCreatedEvent), typeof(UserCreatedEventHandler))
    })
    .Build();

🔄 管道和中间件

Mediator.Net 支持五种不同场景的管道类型:

管道架构

管道类型

管道 描述 触发对象
GlobalReceivePipeline 对所有消息执行 命令、请求、事件
CommandReceivePipeline 仅对命令执行 ICommand
RequestReceivePipeline 仅对请求执行 IRequest
EventReceivePipeline 仅对事件执行 IEvent
PublishPipeline 当事件被发布时执行 IEvent(出站)

创建自定义中间件

1. 创建中间件扩展

public static class LoggingMiddleware
{
    public static void UseLogging<TContext>(
        this IPipeConfigurator<TContext> configurator, 
        ILogger logger = null)
        where TContext : IContext<IMessage>
    {
        logger ??= configurator.DependencyScope?.Resolve<ILogger>();
        configurator.AddPipeSpecification(new LoggingMiddlewareSpecification<TContext>(logger));
    }
}

2. 创建中间件规范

public class LoggingMiddlewareSpecification<TContext> : IPipeSpecification<TContext> 
    where TContext : IContext<IMessage>
{
    private readonly ILogger _logger;

    public LoggingMiddlewareSpecification(ILogger logger)
    {
        _logger = logger;
    }

    public bool ShouldExecute(TContext context, CancellationToken cancellationToken) => true;

    public Task BeforeExecute(TContext context, CancellationToken cancellationToken)
    {
        _logger.LogInformation("正在处理消息:{MessageType}", context.Message.GetType().Name);
        return Task.CompletedTask;
    }

    public Task Execute(TContext context, CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    public Task AfterExecute(TContext context, CancellationToken cancellationToken)
    {
        _logger.LogInformation("完成处理:{MessageType}", context.Message.GetType().Name);
        return Task.CompletedTask;
    }

    public void OnException(Exception ex, TContext context)
    {
        _logger.LogError(ex, "处理消息时出错:{MessageType}", context.Message.GetType().Name);
        throw ex;
    }
}

配置管道

var mediator = new MediatorBuilder()
    .RegisterHandlers(typeof(Program).Assembly)
    .ConfigureGlobalReceivePipe(x => x.UseLogging())
    .ConfigureCommandReceivePipe(x => x.UseValidation())
    .ConfigureRequestPipe(x => x.UseCaching())
    .ConfigureEventReceivePipe(x => x.UseEventStore())
    .ConfigurePublishPipe(x => x.UseOutboxPattern())
    .Build();

🏗️ 依赖注入集成

Microsoft.Extensions.DependencyInjection

Install-Package Mediator.Net.MicrosoftDependencyInjection
services.AddMediator(builder => 
{
    builder.RegisterHandlers(typeof(Program).Assembly);
});

Autofac

Install-Package Mediator.Net.Autofac
var builder = new ContainerBuilder();
var mediatorBuilder = new MediatorBuilder()
    .RegisterHandlers(typeof(Program).Assembly);

builder.RegisterMediator(mediatorBuilder);
var container = builder.Build();

其他支持的容器

🔌 官方中间件包

Serilog 日志

Install-Package Mediator.Net.Middlewares.Serilog
.ConfigureGlobalReceivePipe(x => x.UseSerilog(LogEventLevel.Information))

工作单元

Install-Package Mediator.Net.Middlewares.UnitOfWork

为事务操作提供 CommittableTransaction 支持。

EventStore 集成

Install-Package Mediator.Net.Middlewares.EventStore

自动将事件持久化到 EventStore。

🎯 高级特性

上下文服务

在中间件和处理器之间共享服务:

// 在中间件中
public Task Execute(TContext context, CancellationToken cancellationToken)
{
    context.RegisterService(new AuditInfo { Timestamp = DateTime.UtcNow });
    return Task.CompletedTask;
}

// 在处理器中
public async Task Handle(IReceiveContext<MyCommand> context, CancellationToken cancellationToken)
{
    if (context.TryGetService(out AuditInfo auditInfo))
    {
        // 使用审计信息
    }
}

从处理器发布事件

public async Task Handle(IReceiveContext<CreateOrderCommand> context, CancellationToken cancellationToken)
{
    // 处理命令
    var order = new Order(context.Message.CustomerId);
    
    // 发布领域事件
    await context.Publish(new OrderCreatedEvent 
    { 
        OrderId = order.Id, 
        CustomerId = order.CustomerId 
    });
}

📚 文档

更详细的文档、示例和高级场景,请访问我们的 Wiki

🤝 贡献

我们欢迎贡献!请查看我们的贡献指南了解详情。

📄 许可证

本项目采用 MIT 许可证 - 详情请参阅 LICENSE.txt 文件。

🙋‍♂️ 支持


⭐ 如果您觉得这个项目有用,请给它一个星标!