MST

星途 面试题库

面试题:C# 中 MediatR 框架的管道行为与事务处理

在一个复杂的业务流程中,存在多个步骤,每个步骤可能涉及数据库操作,并且需要保证整个流程的事务性。结合 MediatR 框架的管道行为,说明如何设计一个通用的事务处理机制,以确保业务操作的原子性。请详细描述设计思路以及关键代码结构。
22.3万 热度难度
编程语言C#

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义事务处理管道行为:利用 MediatR 的管道行为特性,创建一个用于处理事务的管道行为类。该类将在请求处理的前后执行事务相关操作。
  2. 事务管理:在管道行为类中,使用数据库上下文(如 Entity Framework Core 的 DbContext)来管理事务。在请求处理前开启事务,请求处理成功后提交事务,若处理过程中出现异常则回滚事务。
  3. 依赖注入:通过依赖注入将数据库上下文传递给事务处理管道行为类,以确保其能够正确操作数据库。
  4. 全局注册:将事务处理管道行为注册到 MediatR 的管道中,使其能够应用到所有需要事务处理的请求上。

关键代码结构

  1. 事务处理管道行为类
using MediatR;
using Microsoft.EntityFrameworkCore;
using System.Threading;
using System.Threading.Tasks;

public class TransactionBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    private readonly DbContext _dbContext;

    public TransactionBehavior(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
    {
        var transaction = await _dbContext.Database.BeginTransactionAsync(cancellationToken);
        try
        {
            var response = await next();
            await _dbContext.SaveChangesAsync(cancellationToken);
            await transaction.CommitAsync(cancellationToken);
            return response;
        }
        catch
        {
            await transaction.RollbackAsync(cancellationToken);
            throw;
        }
    }
}
  1. 注册事务处理管道行为 在应用程序的启动配置(如 Startup.cs)中注册事务处理管道行为:
using MediatR;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 其他服务注册
        services.AddMediatR(typeof(Startup));
        services.AddScoped(typeof(IPipelineBehavior<,>), typeof(TransactionBehavior<,>));
    }
}

这样,当任何请求通过 MediatR 处理时,事务处理管道行为会自动介入,确保整个业务流程的事务性和操作的原子性。