如何在MassTransit中通过依赖注入解析IFilter
问题描述
我正在遵循MassTransit官方文档创建消息类型过滤器,但发现示例中的Filter实例是手动创建的:
public class ExceptionLoggerSpecification<T> : IPipeSpecification<T> where T : class, PipeContext { public IEnumerable<ValidationResult> Validate() { return Enumerable.Empty<ValidationResult>(); } public void Apply(IPipeBuilder<T> builder) { builder.AddFilter(new ExceptionLoggerFilter<T>()); } }
我的问题是:当Filter存在需要解析的依赖项时,如何通过依赖注入来处理其实例化?
解决方案
要让Filter支持依赖注入,需按以下三步处理:注册Filter到DI容器、修改Specification从容器解析Filter、将Specification应用到MassTransit管道。
1. 定义带依赖的Filter
先创建包含依赖的Filter类,比如注入日志组件:
public class ExceptionLoggerFilter<T> : IFilter<T> where T : class, PipeContext { private readonly ILogger<ExceptionLoggerFilter<T>> _logger; // 通过构造函数注入依赖 public ExceptionLoggerFilter(ILogger<ExceptionLoggerFilter<T>> logger) { _logger = logger; } public async Task Send(T context, IPipe<T> next) { try { await next.Send(context); } catch (Exception ex) { _logger.LogError(ex, "消息处理失败"); throw; } } public void Probe(ProbeContext context) { context.CreateFilterScope("exceptionLogger"); } }
2. 修改Specification从DI容器解析Filter
有两种常用实现方式:
方式一:手动通过IServiceProvider解析
让Specification接收IServiceProvider,在Apply方法中解析Filter实例:
public class ExceptionLoggerSpecification<T> : IPipeSpecification<T> where T : class, PipeContext { private readonly IServiceProvider _serviceProvider; // 构造函数注入IServiceProvider public ExceptionLoggerSpecification(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IEnumerable<ValidationResult> Validate() { return Enumerable.Empty<ValidationResult>(); } public void Apply(IPipeBuilder<T> builder) { // 从DI容器获取Filter实例 var filter = _serviceProvider.GetRequiredService<ExceptionLoggerFilter<T>>(); builder.AddFilter(filter); } }
方式二:使用MassTransit内置的ResolveFilter
MassTransit提供了ResolveFilter<TFilter, TContext>,可自动从DI容器解析Filter,无需手动处理IServiceProvider:
public class ExceptionLoggerSpecification<T> : IPipeSpecification<T> where T : class, PipeContext { public IEnumerable<ValidationResult> Validate() { return Enumerable.Empty<ValidationResult>(); } public void Apply(IPipeBuilder<T> builder) { // 让MassTransit自动从DI容器解析ExceptionLoggerFilter<T> builder.AddFilter(new ResolveFilter<ExceptionLoggerFilter<T>, T>()); } }
3. 注册Filter并应用Specification
在DI容器中注册Filter,然后将Specification添加到MassTransit的管道配置中:
// 注册Filter,生命周期建议使用Scoped(和消息上下文生命周期一致) builder.Services.AddScoped(typeof(ExceptionLoggerFilter<>)); // 配置MassTransit时应用Specification builder.Services.AddMassTransit(x => { x.UsingRabbitMq((context, cfg) => { // 全局发送管道应用过滤器 cfg.ConfigureSend(send => { send.AddPipeSpecification(new ExceptionLoggerSpecification<SendContext>(context)); }); // 或者给指定接收端点应用过滤器 cfg.ReceiveEndpoint("demo-queue", e => { e.AddPipeSpecification(new ExceptionLoggerSpecification<ConsumeContext>(context)); }); }); });
内容的提问来源于stack exchange,提问作者dmorganb
相关产品推荐
相关产品推荐

