工业上位机项目的完整 MediatR 管道行为(Pipeline Behaviors)示例代码
** 工业上位机项目的完整 MediatR 管道行为(Pipeline Behaviors)示例代码**,包含工业级推荐的 4 个核心 Behavior。
1. 标记接口(推荐使用)
// MaxWell.Application/CQRS/Base/ICommand.cspublicinterfaceICommand<outTResponse>:IRequest<TResponse>{}// MaxWell.Application/CQRS/Base/IQuery.cspublicinterfaceIQuery<outTResponse>:IRequest<TResponse>{}// MaxWell.Application/CQRS/Base/ITransactionalCommand.cspublicinterfaceITransactionalCommand{}// 需要事务的 Command 实现此接口2. 完整管道行为代码
Behavior 1:验证行为(ValidationBehavior)
// MaxWell.Application/Behaviors/ValidationBehavior.csusingFluentValidation;usingMediatR;usingSystem.Linq;namespaceMaxWell.Application.Behaviors;publicclassValidationBehavior<TRequest,TResponse>:IPipelineBehavior<TRequest,TResponse>whereTRequest:IRequest<TResponse>{privatereadonlyIEnumerable<IValidator<TRequest>>_validators;publicValidationBehavior(IEnumerable<IValidator<TRequest>>validators){_validators=validators;}publicasyncTask<TResponse>Handle(TRequestrequest,RequestHandlerDelegate<TResponse>next,CancellationTokenct){if(_validators==null||!_validators.Any())returnawaitnext();varcontext=newValidationContext<TRequest>(request);varvalidationResults=awaitTask.WhenAll(_validators.Select(v=>v.ValidateAsync(context,ct)));varfailures=validationResults.SelectMany(r=>r.Errors).Where(f=>f!=null).ToList();if(failures.Count>0){varerrorMessage=string.Join(Environment.NewLine,failures.Select(f=>f.ErrorMessage));thrownewValidationException($"命令验证失败:{errorMessage}");}returnawaitnext();}}Behavior 2:日志 + 性能监控行为
// MaxWell.Application/Behaviors/LoggingAndPerformanceBehavior.csusingMediatR;usinglog4net;usingSystem.Diagnostics;usingSystem.Text.Json;namespaceMaxWell.Application.Behaviors;publicclassLoggingAndPerformanceBehavior<TRequest,TResponse>:IPipelineBehavior<TRequest,TResponse>whereTRequest:IRequest<TResponse>{privatestaticreadonlyILog_logger=LogManager.GetLogger("MediatR");publicasyncTask<TResponse>Handle(TRequestrequest,RequestHandlerDelegate<TResponse>next,CancellationTokenct){varrequestName=typeof(TRequest).Name;varsw=Stopwatch.StartNew();try{_logger.Info($"[MediatR START]{requestName}|{JsonSerializer.Serialize(request)}");varresponse=awaitnext();sw.Stop();varsuccess=responseisHardwareResulthr?hr.IsSuccess.ToString():"OK";_logger.Info($"[MediatR END]{requestName}| Success:{success}| 耗时:{sw.ElapsedMilliseconds}ms");returnresponse;}catch(Exceptionex){sw.Stop();_logger.Error($"[MediatR ERROR]{requestName}| 耗时:{sw.ElapsedMilliseconds}ms",ex);throw;}}}Behavior 3:事务行为(仅针对需要事务的命令)
// MaxWell.Application/Behaviors/TransactionBehavior.csusingMediatR;usingMaxWell.Infrastructure.Persistence;namespaceMaxWell.Application.Behaviors;publicclassTransactionBehavior<TRequest,TResponse>:IPipelineBehavior<TRequest,TResponse>whereTRequest:IRequest<TResponse>{privatereadonlyAppDbContext_dbContext;publicTransactionBehavior(AppDbContextdbContext){_dbContext=dbContext;}publicasyncTask<TResponse>Handle(TRequestrequest,RequestHandlerDelegate<TResponse>next,CancellationTokenct){// 只对标记了 ITransactionalCommand 的命令启用事务if(requestisnotITransactionalCommand)returnawaitnext();awaitusingvartransaction=await_dbContext.Database.BeginTransactionAsync(ct);try{varresponse=awaitnext();awaittransaction.CommitAsync(ct);returnresponse;}catch(Exception){awaittransaction.RollbackAsync(ct);throw;}}}Behavior 4:异常统一处理 + 短路行为(可选增强)
// MaxWell.Application/Behaviors/ExceptionHandlingBehavior.cspublicclassExceptionHandlingBehavior<TRequest,TResponse>:IPipelineBehavior<TRequest,TResponse>whereTRequest:IRequest<TResponse>{privatestaticreadonlyILog_logger=LogManager.GetLogger("MediatR.Exception");publicasyncTask<TResponse>Handle(TRequestrequest,RequestHandlerDelegate<TResponse>next,CancellationTokenct){try{returnawaitnext();}catch(ValidationExceptionvex){_logger.Warn($"验证失败:{typeof(TRequest).Name}",vex);throw;}catch(Exceptionex){_logger.Error($"执行命令时发生未处理异常:{typeof(TRequest).Name}",ex);if(typeof(TResponse)==typeof(HardwareResult)){return(TResponse)(object)HardwareResult.Fail($"系统异常:{ex.Message}");}throw;}}}5. 在 App.xaml.cs 中注册(关键)
protectedoverridevoidRegisterTypes(IContainerRegistrycontainerRegistry){varservices=newServiceCollection();// ... 其他注册(DbContext、DeviceManager 等)services.AddMediatR(cfg=>{cfg.RegisterServicesFromAssembly(typeof(StartExperimentCommand).Assembly);});// 管道行为注册顺序非常重要(由外到内)services.AddTransient(typeof(IPipelineBehavior<,>),typeof(ValidationBehavior<,>));services.AddTransient(typeof(IPipelineBehavior<,>),typeof(ExceptionHandlingBehavior<,>));services.AddTransient(typeof(IPipelineBehavior<,>),typeof(LoggingAndPerformanceBehavior<,>));services.AddTransient(typeof(IPipelineBehavior<,>),typeof(TransactionBehavior<,>));_serviceProvider=services.BuildServiceProvider();containerRegistry.RegisterInstance(_serviceProvider);}使用效果:
当执行以下代码时:
varresult=await_mediator.Send(newStartExperimentCommand(...));会依次经过:
- 验证 → 2. 异常处理 → 3. 日志记录 → 4. 事务(如果需要)→ Handler → 后置日志
推荐:
- ValidationBehavior放在最外层
- ExceptionHandlingBehavior紧随其后
- Logging放在中间
- Transaction放在最内层(接近业务)
