RabbitMQ Exchange with Docker in .NET
Tags: dotnet, rabbitmq, amqp, docker
Published: 2021-03-07 09:48:48

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

---

This is the second article from a series of four about RabbitMQ `Exchange` in .NET. In the first part of this article, the fundamentals and the types of the `Exchange` will be presented. And in the second part, each line of code will be explained about how the `Exchange` will be created. The first article, <https://stefanescueduard.github.io/2020/02/29/rabbitmq-producer-with-docker-in-dotnet/>, contains a short introduction to RabbitMQ concepts, the Environment setup with Docker, and `Producer` creation in .NET.

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

The RabbitMQ `Exchange` is used to route the messages received from the `Producer` and sending them to the `Queue` based on the `routing key` key and `binding key`. Those two keys were explained in the first article, so if you want to find the explanation behind them, read the first article.\
An `Exchange` can be one of these four types:

### [](https://eduardstefanescu.dev/2020/03/07/rabbitmq-exchange-with-docker-in-dotnet/#Exchange-types "Exchange types")`Exchange` types

1.  `Direct Exchange` send messages to the `Queues` that have the `binding key` the same as the `routing key`.

2.  `Fanout Exchange` send messages to all the `Queues`, in an indiscriminate way. It uses the Publish-Subscribe Pattern, which means that all `Queues` that are subscribed to an `Exchange` will receive the message, like a newsletter. Also, it will not take into account the `binding` or the `routing` key.

3.  `Topic Exchange` send messages to the `Queues` using a pattern. The pattern can contain `*` or `#`. The first wildcard `*` means that it can match any word, and the second one `#` represents that no word is expected in that place.

    For example, if there are three `Queues`, and each one expects to get a 'word' based on the `binding key`, as follows:

     Queue1 > word1._._

     Queue2 > _.word2._

     Queue3 > _._.word3

    If the `Producer` sends the message `word1.word2.word3`, each `Queue` will receive only the expected message.

    A real-life example for this type of `Exchange` can be the different levels of logging (i.e. the errors and warns can be sent to the Database, and the info ones sent to a file).

4.  `Headers Exchange` send messages based on a header, this header is represented by a required property `x-match` and one or more properties that will be bound to the `Queue` like a `routing-key`. This type of `Exchange` is useful when the message should follow the header values and not the `routing keys`. It's also associated with the `Topic Exchange`, but it's much more flexible, with the disadvantage that the message should be an object.

A topology can have multiple `Exchanges` connected to the multiple `Producers` and `Queues`, as in the example below, made using [http://tryrabbitmq.com](http://tryrabbitmq.com/).

![Exchange Multiple Connections](https://eduardstefanescu.dev/2020/03/07/rabbitmq-exchange-with-docker-in-dotnet/exchange-multiple-connections.png)

Short explanation; the `Producers` can be seen as Clients, the `Queues` as Buffers or as Preprocessor and the `Consumers` are the applications that receive the messages. In this example the Clients can be considered as a mobile application that sent two requests to the server in order to persist some data, the Buffers are like a middleware that scans the data, and the `Consumers` are different storages that save the data based on its file type.

[](https://eduardstefanescu.dev/2020/03/07/rabbitmq-exchange-with-docker-in-dotnet/#Creating-the-Exchange "Creating the Exchange")Creating the `Exchange`
---------------------------------------------------------------------------------------------------------------------------------------------------------

This project only covers the first tree `Exchange` types (i.e. Direct, Fanout and Topic), because the Headers type is a little more special I want to make another article just for it.

This, like the rest of the projects, is a Console Application. First of all, the user is asked which of `Exchange` wants to create:
```
Console.Write("Exchange type (fanout, direct, topic): ");
var exchangeType = Console.ReadLine();
```
Then the connection to the RabbitMQ Server is created using the URI.
```
var factory = new ConnectionFactory
{
  Uri = new Uri("amqp://guest:guest@localhost"),
  ContinuationTimeout = TimeSpan.MaxValue
};
```
In the first article, the connection is created by specifying each property needed. Here the `URI` consists of following parts: the first one is the protocol used, in this case, `AMQP`, then the `username` and the `password`, and the last section is the `hostname` or the `IP` of the RabbitMQ server. The `URI` can also contain the port, here the default one is 5672.\
The `ConnectionTimeout` is set to the maximum value because the application is desired to run indefinitely, and this value is used to bypass the connection time out.

### [](https://eduardstefanescu.dev/2020/03/07/rabbitmq-exchange-with-docker-in-dotnet/#Exchange-definition "Exchange definition")`Exchange` definition

In order to establish the connection between our machine and the RabbitMQ Server, the stream must be opened, and through this stream, the information is sent using a Channel.
```
using (IConnection connection = factory.CreateConnection())
{
  using (IModel channel = connection.CreateModel())
  {
    const string exchangeName = "test-exchange";
    channel.ExchangeDelete(exchangeName);
    channel.ExchangeDeclare(exchangeName, exchangeType);
  }
}
```
The exchange name will have the same name for all four projects but is just for this article presentation purposes. On line 6 a safety deletion is executed in order, to ensure that on the next line when the Exchange will be created, there is no other `Exchange` with the same name. The `ExchangeDeclare` method will create an instance of an `Exchange` based on what type of `Exchange` the user has chosen.

### [](https://eduardstefanescu.dev/2020/03/07/rabbitmq-exchange-with-docker-in-dotnet/#Prompting-the-definition-result "Prompting the definition result")Prompting the definition result

In the last section of the code, the user is informed that the required `Exchange` was created. You may notice that I didn't do any type of exception handling, that's because it's only for this article presentation. But in a real-world application, I recommend implementing a strong exception handling system and make the other services involved aware if that happens.

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

Let's create a `Direct Exchange`, which will also appear on the RabbitMQ Management plugin.

![Exchange Created Successfully](https://eduardstefanescu.dev/2020/03/07/rabbitmq-exchange-with-docker-in-dotnet/exchange-created-successfully.png)

And now let's check the Management Exchange page.

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

As is showed on this page the `test-exchange` `Exchange` was created with the type that the user wanted and is ready to be used.

On the `test-exchange` dashboard, there a message can be published, as we did in the first article with the `Producer`. I will demonstrate both ways of publishing the messages in the last article, where the entire system will be connected. And also the `Exchange` can be deleted.

![test-exchange page](https://eduardstefanescu.dev/2020/03/07/rabbitmq-exchange-with-docker-in-dotnet/test-exchange-page.png)

Because the topology currently doesn't have connected all needed components, on the `Message rates` the `Idle` message is displayed, but we'll see that after the entire system is running, there will be a chart that will show the messages flow, as Publish (In) and Publish (Out).

All the code from the entire solution is available on my Github account: <https://github.com/StefanescuEduard/RabbitMQ_POC>. But stay close because in the next articles I will explain the core concepts about each RabbitMQ node.

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.