RabbitMQ Queue with Docker in .NET
Tags: amqp, docker, rabbitmq, dotnet
Published: 2021-03-07 09:52:47

Originally published at https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/.

---

This is the third article from a series of four about RabbitMQ `Queue`. The first part contains a brief introduction into the `Queue` concepts and in the second part, each line of the code is explained. You can check the first article where the RabbitMQ core concepts are presented and also the environment setup with Docker and the `Producer` are explained step by step.

[](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/#Introduction "Introduction")Introduction
-------------------------------------------------------------------------------------------------------------------------

The RabbitMQ `Queue` is positioned in the `Message Broker` section with the `Exchange`, and can be seen as buffer storage, that receives messages through a stream based on the `binding key` from the `Exchange` which also receives the messages from one or many `Producers`. They are acting like a Queue Data Structure, that can be `enqueued` and `dequeued`, using the FIFO rule.\
Some tips about the `Queues`, that I find useful are:

-   A `Queue` name can't start the `amq` name, because is restricted by the `Broker` for internal usages.
-   If the `Queue` name is not specified a random one will be assigned to it.
-   `Queues` with the same name can be created on the same channel, by only the last one will be kept.

All the RabbitMQ `Queue` properties can be on their site: <https://www.rabbitmq.com/queues.html>.

[](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/#Creating-the-Queue "Creating the Queue")Creating the `Queue`
---------------------------------------------------------------------------------------------------------------------------------------------

To start creating a `Queue` firstly the connection to the RabbitMQ server should be built using the `ConnectionFactory`; is the same setup as in the previous article about RabbitMQ `Exchange` using a `URI`. But in the first article where the `Producer` is created, the connection was created using explicit properties of `ConnectionFactory` (i.e. `Hostname`, `UserName` and `Password`).

### [](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/#Connection-setup "Connection setup")Connection setup

As you can see in the below chunk code, all these properties are embedded into one `Uri` instance.
```
var factory = new ConnectionFactory
{
    Uri = new Uri("amqp://guest:guest@localhost"),
    ContinuationTimeout = TimeSpan.MaxValue
};
```
`ConnectionTimeout` property was set to its maximum value because I didn't want the connection to expire, but this is just for this article purposes. If you are interested to find all the `ConnectionFactory` properties, they are well documented here with one example: <https://www.rabbitmq.com/releases/rabbitmq-dotnet-client/v3.2.4/rabbitmq-dotnet-client-3.2.4-client-htmldoc/html/type-RabbitMQ.Client.ConnectionFactory.html>. This is the documentation for version 3.2.4 when you read this article the RabbitMQ Client for .NET may be updated, so it's possible that some properties may be changed, deprecated or removed.

### [](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/#Developer-input "Developer input")Developer input

You may wonder why the user or the developer input is involved in this, is because this series of articles about `RabbitMQ` is more educational rather than a solution-oriented approach. So I wanted to replicate one to one the <http://tryrabbitmq.com/> concept of learning the basic principles of RabbitMQ using .NET.\
Thus, after the connection to the RabbitMQ Server was built, the user is asked to enter the number of `Queues` that he wants to create and to provide for each `Queue` a name and the `routing key`.
```
for (var queueIndex = 0; queueIndex < queuesCount; queueIndex++)
{
    Console.Write($"Queue[{queueIndex}] name: ");
    var queueName = Console.ReadLine();

    Console.Write($"Routing key for Queue[{queueIndex}]: ");
    var routingKey = Console.ReadLine();
...
```
### [](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/#Connection-establishment "Connection establishment")Connection establishment

When the required properties are entered, for each `Queue` a `Connection` and a communication `Channel` will be created. After that, the `Queue` is declared, and the bound to the `Exchange` that has the same name for the entire solution (i.e. test-exchange). If the creation and the binding were ended successfully, then a message is prompted informing the user that the `Queue` was created.
```
...
    using (IConnection connection = factory.CreateConnection())
    {
        using (channel = connection.CreateModel())
        {
            channel.QueueDeclare(queue: queueName,
                durable: false,
                exclusive: false,
                autoDelete: false,
                arguments: null);

            channel.QueueBind(queue: queueName,
                exchange: "test-exchange",
                routingKey: routingKey);
        }
    }

    Console.WriteLine(value: $"Queue {queueName} created.");
}
```
#### [](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/#QueueDeclare-parameters "QueueDeclare parameters")`QueueDeclare` parameters

Let's dig a little bit deep into the parameters of the `QueueDeclare`:

-   `queue` it's self-evident that it refers to the `Queue` name;
-   `durable` represents the lifetime of the `Queue` in the `Broker`, if it's set to false the `Queue` will end when the `Broker` does too;
-   `autoDelete` is used to specify the lifetime of the `Queue` based on its subscriptions. The `Queue` will be deleted if the last `Consumer` subscribed to it, unsubscribes;
-   `arguments` are used to sent information about the `Queue` (e.g. length limit) to the `Broker`;

`QueueBind`'s parameters are self-explanatory, the first one refers to the `queueName`, the second to the `exchangeName` and the last one to the `routingKey`.

#### [](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/#The-result "The result")The result

After the `Queues` are created, a message is prompted to the user with how many `Queues` were created.

![RabbitMQ Queue Created Console](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/rabbitmq-queue-created-console.png)

The created `Queues` can also be seen on the RabbitMQ Management page.

![RabbitMQ Queue Created Management](https://eduardstefanescu.dev/2020/03/14/rabbitmq-queue-with-docker-in-dotnet/rabbitmq-queue-created-management.png)

Now, all we have to do is to create the `Consumer`, and the entire topology will be ready to be used. The `Consumer` will be created in the next article, this being the last one from this series.

Thanks for reading this article, if you find it interesting please share it with your colleagues and friends. Or if you find something that can be improved please let me know.