C# 连接到RabbitMQ,方法级最佳实践?
我有一个使用rabbitmq读写消息的类。我不想在这个类的构造函数中或读写方法中包含与连接相关的信息。相反,我想在使用write和read方法时建立一个连接。解决这个问题的最佳方法/实践是什么 //编辑1C# 连接到RabbitMQ,方法级最佳实践?,c#,methods,rabbitmq,amqp,C#,Methods,Rabbitmq,Amqp,我有一个使用rabbitmq读写消息的类。我不想在这个类的构造函数中或读写方法中包含与连接相关的信息。相反,我想在使用write和read方法时建立一个连接。解决这个问题的最佳方法/实践是什么 //编辑1 public class Rabbit : IMessageBus { // Implementation of methods for Rabbit class go here private List<string> publishQ = new List
public class Rabbit : IMessageBus
{
// Implementation of methods for Rabbit class go here
private List<string> publishQ = new List<string>();
private List<string> subscribeQ = new List<string>();
ConnectionFactory factory = null;
IConnection connection = null;
IModel channel = null;
QueueingBasicConsumer consumer = null;
public void write ( Measurement m1 )
{
byte[] body = Measurement.AltSerialize( m1 );
foreach (string queue in publishQ)
{
channel.BasicPublish("", queue, null, body);
Console.WriteLine("\n [x] Sent to queue {0}.", queue);
}
}
public void publish(string queueName)
{
channel.QueueDeclare(queueName, true, false, false, null); //durable=true
publishQ.Add(queueName); //and, add it the list of queue names to publish to
}
public Measurement read()
{
foreach (string queue in subscribeQ)
{
channel.BasicConsume(queue, true, consumer);
}
System.Console.WriteLine(" [*] Waiting for messages." +
"To exit press CTRL+C");
BasicDeliverEventArgs ea =
(BasicDeliverEventArgs)consumer.Queue.Dequeue();
return Measurement.AltDeSerialize(ea.Body);
}
public void subscribe(string queueName)
{
channel.QueueDeclare(queueName, true, false, false, null);
subscribeQ.Add(queueName);
}
public static string MsgSysName;
public string MsgSys
{
get
{
return MsgSysName;
}
set
{
MsgSysName = value;
}
}
public Rabbit(string _msgSys) //Constructor
{
factory = new ConnectionFactory();
factory.HostName = "localhost";
connection = factory.CreateConnection();
channel = connection.CreateModel();
consumer = new QueueingBasicConsumer(channel);
System.Console.WriteLine("\nMsgSys: RabbitMQ");
MsgSys = _msgSys;
}
~Rabbit()
{
//
}
}
公共类兔子:IMessageBus
{
//Rabbit类方法的实现
private List publishQ=新列表();
private List subscribeQ=新列表();
ConnectionFactory=null;
i连接=空;
IModel通道=空;
QueueingBasicConsumer消费者=null;
公共无效写入(度量m1)
{
字节[]体=测量值。AltSerialize(m1);
foreach(publishQ中的字符串队列)
{
channel.BasicPublish(“”,队列,null,主体);
WriteLine(“\n[x]已发送到队列{0}.”,队列);
}
}
公共无效发布(字符串队列名称)
{
channel.QueueDeclare(queueName,true,false,false,null);//持久=true
Add(queueName);//并将其添加到要发布到的队列名称列表中
}
公共计量读数()
{
foreach(subscribeQ中的字符串队列)
{
channel.BasicConsume(队列、true、消费者);
}
System.Console.WriteLine(“[*]正在等待消息。”+
“要退出,请按CTRL+C”);
基本交付事件参数ea=
(BasicDeliverEventArgs)consumer.Queue.Dequeue();
返回测量。反序列化(ea.Body);
}
public void subscribe(字符串queueName)
{
QueueDeclare(queueName,true,false,false,null);
subscribeQ.Add(queueName);
}
公共静态字符串MsgSysName;
公共字符串MsgSys
{
得到
{
返回MsgSysName;
}
设置
{
MsgSysName=值;
}
}
公共兔子(字符串_msgSys)//构造函数
{
工厂=新连接工厂();
factory.HostName=“localhost”;
connection=factory.CreateConnection();
channel=connection.CreateModel();
消费者=新排队基本消费者(通道);
System.Console.WriteLine(“\nMsgSys:RabbitMQ”);
MsgSys=_MsgSys;
}
~Rabbit()
{
//
}
}
您是否考虑过将Func
传递给构造函数?换句话说,当你想要连接的时候,你能得到连接吗
(显然,您需要将连接信息传递到某个地方,除非您打算静态访问它……不寒而栗。)
编辑:好的,我不熟悉RabbitMQ,但是假设它有某种实现了IDisposable
的连接
类,它看起来会像这样:
public class MessageHandler
{
private readonly Func<Connection> connectionProvider;
public MessageHander(Func<Connection> connectionProvider)
{
this.connectionProvider = connectionProvider;
}
public void WriteMessage(string message)
{
using (Connection connection = connectionProvider.Invoke())
{
connection.DoSomething(message);
}
}
}
现在,如果有更“有趣”的内容,您可能需要编写一个单独的
ConnectionProvider
类。当然,RabbitMQ可能有一些示例代码—您应该首先查阅这些代码和它们的文档,因为我不知道我在说什么:)没有,但这听起来是个好主意。我该怎么做?你能给我举个简单的例子吗?我也编辑了我的问题。它现在有了我正在学习的课程。但是,您是否仍在初始化构造函数(因此整个类都要使用该连接?@Demi:No,它正在向构造函数传递获取连接的方法。在您请求之前,它不会创建连接。(你应该看看下面的.NET命名约定,顺便说一下…)仅供参考,你正在到处泄漏资源。其中有几个类是可识别的。终结器是邪恶的-去掉那个空的!
MessageHandler handler = new MessageHandler(() => new Connection(server));