.NET7下EasynetQ AutoSubscriber消费者依赖注入配置问题
解决EasyNetQ AutoSubscriber在.NET7中依赖注入消费者的问题
默认情况下EasyNetQ的AutoSubscriber使用Activator.CreateInstance创建消费者实例,这要求消费者必须有无参构造函数。要实现依赖注入,需要让AutoSubscriber使用.NET的DI容器来解析消费者实例,具体步骤如下:
步骤1:修正消费者的依赖注入定义
确保消费者的构造函数使用正确的依赖类型,比如ILogger<T>而非非泛型的ILogger(否则DI容器无法解析):
public class MessageConsumer : IConsumeAsync<Message> { private readonly ILogger<MessageConsumer> _logger; public MessageConsumer(ILogger<MessageConsumer> logger) { _logger = logger; } public async Task ConsumeAsync(Message message, CancellationToken cancellationToken = default) { // 业务逻辑 _logger.LogInformation("Received message: {Message}", message); } }
步骤2:注册消费者到DI容器
在启动类中,将消费者注册到.NET的服务容器(根据业务需求选择AddScoped/AddTransient/AddSingleton):
var builder = WebApplication.CreateBuilder(args); var ConnectionString = builder.Configuration.GetConnectionString("RabbitMQ"); // 创建并注册EasyNetQ总线 var bus = RabbitHutch.CreateBus(ConnectionString); builder.Services.AddSingleton<IBus>(bus); // 注册消费者到DI容器 builder.Services.AddScoped<MessageConsumer>();
步骤3:配置AutoSubscriber使用DI容器创建实例
构建服务提供者后,配置AutoSubscriber的ConsumerFactory,让它从DI容器中解析消费者实例,再执行订阅:
var app = builder.Build(); // 从DI容器获取总线实例 var bus = app.Services.GetRequiredService<IBus>(); // 初始化AutoSubscriber var subscriber = new AutoSubscriber(bus, "Test") { // 设置消费者工厂,使用DI容器解析实例 ConsumerFactory = type => app.Services.GetRequiredService(type) }; // 扫描当前程序集并订阅所有消费者 await subscriber.SubscribeAsync(Assembly.GetExecutingAssembly()); // 其他中间件配置... app.Run();
额外说明
- 修正发布类的命名错误:你的发布类
Test的构造函数名为RabbitPublisher,不符合C#语法,应将类名改为RabbitPublisher:
public class RabbitPublisher { private readonly IBus _bus; public RabbitPublisher(IBus bus) { _bus = bus; } public async Task PublishAsync<T>(T messageContent) { await _bus.PubSub.PublishAsync(messageContent); } }
- 如果需要批量注册消费者,可使用DI扩展扫描程序集自动注册:
// 扫描当前程序集所有实现IConsumeAsync的类并注册为Scoped服务 builder.Services.Scan(scan => scan .FromAssemblies(Assembly.GetExecutingAssembly()) .AddClasses(classes => classes.AssignableTo(typeof(IConsumeAsync<>))) .AsImplementedInterfaces() .WithScopedLifetime());
内容的提问来源于stack exchange,提问作者Sun
相关产品推荐
相关产品推荐

