如何在MassTransit中从依赖项获取RabbitMQ密码?
问题
在使用MassTransit.RabbitMq 8.0.9的.NET Core 3.1(AspNetCore 3.1.10)项目中,RabbitMQ密码存储在密钥库,可通过依赖注入的ISecretRetrieval接口获取,但现有示例均从配置中读取密码。
期望实现:
var secrets = serviceProvider.GetRequiredService<ISecretRetrieval>(); var rabbitPassword = secrets.GetRabbitMqPassword();
然后将该密码传递给IRabbitHostConfigurator,但在UseMassTransit...UseRabbitMq代码块中找不到可用的IServiceProvider实例。
另一种思路:创建构造函数依赖ISecretRetrieval的配置对象,已知可通过自定义类实现IConfiguration<MassTransitHostOptions>的注册,想询问是否可以对RabbitMqHostSettings(接口类型,而非MassTransitHostOptions这类类)执行同样操作?
解决方案
方法一:临时构建ServiceProvider获取密钥
在ConfigureServices中,先注册ISecretRetrieval的实现,再临时构建ServiceProvider获取密码,之后配置MassTransit:
public void ConfigureServices(IServiceCollection services) { // 注册密钥获取服务 services.AddScoped<ISecretRetrieval, YourSecretRetrievalImpl>(); // 临时构建容器获取密码 using var tempSp = services.BuildServiceProvider(); var secrets = tempSp.GetRequiredService<ISecretRetrieval>(); var rabbitPassword = secrets.GetRabbitMqPassword(); services.AddMassTransit(x => { // 配置消费者、端点等逻辑... x.UsingRabbitMq((context, cfg) => { cfg.Host("rabbitmq-host", h => { h.Username("rabbit-username"); h.Password(rabbitPassword); // 配置虚拟主机、端口等其他参数 }); // 其他RabbitMQ配置逻辑... }); }); }
注意:临时构建ServiceProvider可能会导致服务实例重复创建,若ISecretRetrieval是单例/瞬态模式则无影响,若为作用域模式需谨慎。
方法二:通过IConfigureOptions动态配置RabbitMqHostSettings
RabbitMqHostSettings是接口,不能直接实现IConfiguration<RabbitMqHostSettings>,但可以通过IConfigureOptions接口实现动态配置:
- 定义基础RabbitMQ配置类(读取配置文件中的非敏感信息):
public class RabbitMqBasicConfig { public string Host { get; set; } public string Username { get; set; } public string VirtualHost { get; set; } = "/"; }
- 在
appsettings.json中配置基础信息:
{ "RabbitMqBasicConfig": { "Host": "rabbitmq-host", "Username": "rabbit-username", "VirtualHost": "your-vhost" } }
- 实现
IConfigureOptions<RabbitMqHostSettings>,注入ISecretRetrieval获取密码:
public class RabbitMqHostSettingsConfigurer : IConfigureOptions<RabbitMqHostSettings> { private readonly ISecretRetrieval _secretRetrieval; private readonly IConfiguration _configuration; public RabbitMqHostSettingsConfigurer(ISecretRetrieval secretRetrieval, IConfiguration configuration) { _secretRetrieval = secretRetrieval; _configuration = configuration; } public void Configure(RabbitMqHostSettings options) { var basicConfig = _configuration.GetSection("RabbitMqBasicConfig").Get<RabbitMqBasicConfig>(); options.Host = basicConfig.Host; options.Username = basicConfig.Username; options.VirtualHost = basicConfig.VirtualHost; options.Password = _secretRetrieval.GetRabbitMqPassword(); // 按需配置端口、心跳等其他参数 } }
- 注册配置类并配置MassTransit:
public void ConfigureServices(IServiceCollection services) { services.AddScoped<ISecretRetrieval, YourSecretRetrievalImpl>(); services.Configure<RabbitMqBasicConfig>(Configuration.GetSection("RabbitMqBasicConfig")); services.AddTransient<IConfigureOptions<RabbitMqHostSettings>, RabbitMqHostSettingsConfigurer>(); services.AddMassTransit(x => { // 配置消费者、端点等逻辑... x.UsingRabbitMq((context, cfg) => { // 直接使用已配置的RabbitMqHostSettings var hostSettings = context.GetRequiredService<IOptions<RabbitMqHostSettings>>().Value; cfg.Host(hostSettings); // 其他RabbitMQ配置逻辑... }); }); }
内容的提问来源于stack exchange,提问作者babackman
相关产品推荐
相关产品推荐

