Подключение к RabbitMQ, лучшие методы на уровне методов? - PullRequest
1 голос
/ 13 июля 2011

У меня есть класс, который читает и пишет сообщения, используя rabbitmq.Я не хочу иметь информацию, связанную с подключением, в конструкторе этого класса или внутри методов чтения и записи.Вместо этого я хочу установить соединение, когда использую методы записи и чтения.Каков наилучший способ / практика для решения этой проблемы?

// Редактировать 1

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()
    {
        //
    }   
}

1 Ответ

2 голосов
/ 13 июля 2011

Рассматривали ли вы передать Func<Connection> в конструктор? Другими словами, способ, которым вы можете получить соединение , когда вы хотите ?

(Очевидно, вам нужно передать информацию о соединении в где-то , если только вы не собираетесь получить к ней статический доступ ... дрожь.)

РЕДАКТИРОВАТЬ: Хорошо, я не знаком с RabbitMQ, но если предположить, что он имеет какой-то класс Connection, который реализует 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);
        }
    }
}

Затем создайте что-то вроде:

MessageHandler handler = new MessageHandler(() => new Connection(server));

Теперь, если есть что-то более "интересное", вы можете написать отдельный класс ConnectionProvider. Конечно, у RabbitMQ, вероятно, есть некоторый пример кода - вы должны сначала ознакомиться с ним и его документацией, так как я не совсем понимаю, о чем говорю:)

...