June 16 2025
docker run -d --hostname rabbitmq
--name rabbitmq \
-p 5672:5672 -p 15672:15672 rabbitmq:3-management
Install-Package RabbitMQ.Client
public class EmailMessage
{
public string To { get; set; } = default!;
public string Subject { get; set; } = default!;
public string Body { get; set; } = default!;
}
public class EmailMessagePublisher
{
private const string EmailQueue = "email-queue";
public async Task Publish(EmailMessage email)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync();
using var channel = await connection.CreateChannelAsync();
// Ensure the queue exists
await channel.QueueDeclareAsync(queue: EmailQueue,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
// Create a message
var message = JsonSerializer.Serialize(email);
var body = Encoding.UTF8.GetBytes(message);
// Publish the message
await channel.BasicPublishAsync(
exchange: string.Empty,
routingKey: EmailQueue,
mandatory: true,
basicProperties: new BasicProperties { Persistent = true },
body: body);
}
}
public class EmailMessageConsumer : BackgroundService
{
private const string EmailQueue = "email-queue";
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var factory = new ConnectionFactory() { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync(stoppingToken);
using var channel = await connection.CreateChannelAsync(cancellationToken: stoppingToken);
await channel.QueueDeclareAsync(queue: EmailQueue,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null,
cancellationToken: stoppingToken);
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (sender, eventArgs) =>
{
var body = eventArgs.Body.ToArray();
var json = Encoding.UTF8.GetString(body);
var email = JsonSerializer.Deserialize<EmailMessage>(json);
Console.WriteLine($"Sending Email To: {email?.To}, Subject: {email?.Subject}");
// Simulate sending email...
Task.Delay(1000).Wait();
await ((AsyncEventingBasicConsumer)sender).Channel.BasicAckAsync(eventArgs.DeliveryTag, multiple: false);
};
await channel.BasicConsumeAsync(queue: EmailQueue,
autoAck: true,
consumer: consumer,
cancellationToken: stoppingToken);
}
}
channel.ExchangeDeclare("direct-exchange", ExchangeType.Direct);
channel.QueueBind("email-welcome-queue", "direct-exchange", "welcome");
channel.ExchangeDeclare("fanout-exchange", ExchangeType.Fanout);
channel.QueueBind("email-queue", "fanout-exchange", "");
channel.QueueBind("sms-queue", "fanout-exchange", "");
channel.ExchangeDeclare("topic-exchange", ExchangeType.Topic);
channel.QueueBind("error-queue", "topic-exchange", "log.error.#");
channel.QueueBind("auth-queue", "topic-exchange", "log.*.auth");
channel.ExchangeDeclare("headers-exchange", ExchangeType.Headers);
var args = new Dictionary<string, object>
{
{ "x-match", "all" }, // or "any"
{ "x-type", "invoice" },
{ "region", "EU" }
};
channel.QueueBind("invoice-eu-queue", "headers-exchange", string.Empty, args);
1. Design Patterns that Deliver
This isn’t just another design patterns book. Dive into real-world examples and practical solutions to real problems in real applications.Check out it here.
Go-to resource for understanding the core concepts of design patterns without the overwhelming complexity. In this concise and affordable ebook, I've distilled the essence of design patterns into an easy-to-digest format. It is a Beginner level. Check out it here.
Every Monday morning, I share 1 actionable tip on C#, .NET & Arcitecture topic, that you can use right away.
Join 15,250+ subscribers to improve your .NET Knowledge.
Subscribe to the TheCodeMan.net and be among the 15,250+ subscribers gaining practical tips and resources to enhance your .NET expertise.