解决.net核心注入

时间:2021-06-07 15:29:16

标签: c# .net-core dependency-injection

我有一个接口 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));

2 个答案:

答案 0 :(得分:1)

这里有几种方法。这里有两个需要考虑。

  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);
  1. 将完整的列表队列注入 RabbitSender

另一种选择是将消息类型到队列信息的映射注入 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 连接的类,如果你将它们注册为 transientscoped,他们将在每次处置时处置 rabbitMQ 连接,很可能你想避免这种情况