Reputation:
I have an interface IRabbitSender and the implementation RabbitSender
public class RabbitSender : IRabbitSender(){
public RabbitSender(string connection, string queue){
}
public void Send (object info){ // send message to specific queue }
}
I need different instances of the RabbitSender that will send information for different queues/connections. But I only know which instance choose in runtime.
How can I do the DI? Actually, I have this, but I don't know how to distinct both and how to resolve the dependency in runtime.
services.AddTransient<IRabbitSender>(s => new RabbitSender(connection1, queueName1));
services.AddTransient<IRabbitSender>(s => new RabbitSender(connection2, queueName1));
Upvotes: 0
Views: 66
Reputation: 172875
There are several approaches to take here. Here are two to consider.
IRabbitSender<TMessage>
This allows the consumer specifying which message to send, and in your configuration you can map message types to queues (tip: try keeping message names and queue names in sync as a convention; that drastically simplifies your life):
// 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);
Another option is to inject the mapping of messages types to queue information into RabbitSender
. For instance:
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) }
}
Upvotes: 1
Reputation: 6020
You need to new up your RabbitSender
class when you register instance it should be unique to. For example:
services.AddTransient<IRequireUniqueRabbit>(_ => {
return new RequireUniqueRabbit(new RabbitSender(connString1, queue1))
});
services.AddTransient<IRequireUniqueRabbit2>(_ => {
return new RequireUniqueRabbit2(new RabbitSender(connString2, queue2))
});
PS: Think about how you register classes holding the RabbitMQ connection, if you register them as transient
or scoped
they will dispose rabbitMQ connection each time they are disposed, most likely you want to avoid that
Upvotes: 0