我有一个接口 IRabbitSender 和实现 RabbitSender
public class RabbitSender : IRabbitSender(){
public RabbitSender(string connection, string queue){
}
public void Send (object info){ // send message to specific queue }
}
我需要 RabbitSender 的不同实例来为不同的队列/连接发送信息。 但我只知道运行时选择哪个实例。
我该如何做 DI?实际上,我有这个,但我不知道如何区分两者以及如何解决运行时的依赖关系。
services.AddTransient<IRabbitSender>(s => new RabbitSender(connection1, queueName1));
services.AddTransient<IRabbitSender>(s => new RabbitSender(connection2, queueName1));
答案 0 :(得分:1)
这里有几种方法。这里有两个需要考虑。
IRabbitSender<TMessage>
这允许消费者指定要发送的消息,并且在您的配置中您可以将消息类型映射到队列(提示:尝试将消息名称和队列名称保持同步作为约定;这会大大简化您的生活):
// Handy extension method
public static AddSender<TMessage>(
this IServiceCollection services, string con, string queue)
{
services.AddSingleton<IRabbitSender<TMessage>(new RabbitSender(con, queue);
}
// Registrations
services.AddSender<ShipOrder>(connection1, queueName1);
services.AddSender<CancelOrder>(connection2, queueName1);
另一种选择是将消息类型到队列信息的映射注入 RabbitSender
。例如:
public class RabbitSender : IRabbitSender {
private Dictionary<Type, (string connection, string queue)> senders;
public RabbitSender(Dictionary<Type, (string connection, string queue)> senders){
this.senders = senders;
}
public void Send(object info) {
var queueInfo = this.senders[info.GetType];
// TODO: Use queue info to send message to a queue
}
}
// Registration
servies.AddSingleton<IRabbitSender>(new RabbitSender(new Dictionary
{
{ typeof(ShipOrder), (connection1, queueName1) }
{ typeof(CancelOrder), (connection2, queueName1) }
}
答案 1 :(得分:0)
当您注册它应该是唯一的实例时,您需要更新您的 RabbitSender
类。例如:
services.AddTransient<IRequireUniqueRabbit>(_ => {
return new RequireUniqueRabbit(new RabbitSender(connString1, queue1))
});
services.AddTransient<IRequireUniqueRabbit2>(_ => {
return new RequireUniqueRabbit2(new RabbitSender(connString2, queue2))
});
PS:想想你如何注册持有 RabbitMQ 连接的类,如果你将它们注册为 transient
或 scoped
,他们将在每次处置时处置 rabbitMQ 连接,很可能你想避免这种情况