AspNet Core’da RabbitMQ ile E-Posta Gönderim İşlemleri.

Adem Olguner
Devops Türkiye☁️ 🐧 🐳 ☸️
6 min readNov 22, 2019

RabbitMQ nedir, nasıl kurulur, konfigürasyon işlemleri nelerdir gibi soruların cevabını buradaki makalemden okuyabilirsiniz. Bu yazımda RabbitMQ ile mesajlaşma dışında gerçek hayat uygulamalarında nerelerde kullanabiliriz sorusuna cevap bulmaya çalışacağız.

RabbitMQ (MQ- Message Queue) olarakta tanımlayabiliriz.
Publisher -Queue-Consumer hayat döngüsünde çalışan bir yapıdır.

Gelelim örnek projemize;

  • RabbitMQ adında Blank Solution oluşturacağız.
  • RabbitMQ.Core adında .Net Core 2.2 Class Library projesi oluşturacağız.
  • RabbitMQ.WebUI adında .Net Core 2.2 Web Application (MVC) oluşturacağız.
  • RabbitMQ.ConsumerConsole adında .Net Core 2.2 Console Application oluşturacağız.
Solution ve Projeler

RabbitMQ.Core projesinde tüm proje katmanlarında kullanılacak class, Interface, Entity, appsettings ve konfigürasyon işlemlerinin yapılacağı ortak katman olacaktır. Diğer projeler de RabbitMQ.Core projesini referans alacağız.
(Project => Dependencies => Sağ Tık =>Add Reference…)

RabbitMQ.WebUI projesine RabbitMQ.Core referans alıyoruz
RabbitMQ.ConsumerConsole projesine RabbitMQ.Core referans alıyoruz

RabbitMQ.WebUI projesinde RabbitMQ (kuyruğu) besleyen operasyonlar olacaktır (“Mail gönderim işlemi”, mail göndermeden kuyruğa yazacağız).

RabbitMQ.ConsumerConsole projesinde ise RabbitMQ kuyruğunu dinleyen ve mail gönderim operasyonunu yazacağız.

File => New => Project yolunu izleyelim.

Blank Solution seçiyoruz

Solution Project (RabbitMQ)=> Sağ tık => Add => New Project

Asp.Net Core Web Application projesi seçiyoruz RabbitMQ.WebUI

Web Application (MVC Model-View-Controller) türünde seçelim.

Solution Project (RabbitMQ)=> Sağ tık => Add => New Project
Console App
(.Net Core) Projecesi seçiyoruz. RabbitMQ.ConsumerConsole

Console App ():Net Core

Solution Project (RabbitMQ)=> Sağ tık => Add => New Project Class Class Library (.Net Core) projesi seçiyoruz RabbitMQ.Core

Tüm projeleri oluşturduktan sonra Solution alttaki gibi olacaktır.

Solution ve proje katmanları

Gerekli paketleri kurmak için Manage Nuget Packages’i açıyoruz.
Solution (RabbitMQ) => Sağ Tık => Manage Nuget Packages for Solution

Manage Nuget Package kullanarak projelere hangi paketlerin kurulacağı listesi alttadır.

[ RabbitMQ.Core ]
* RabbitMQ.Client
* Newtonsoft.Json
* Ninject
* Microsoft.Extensions.Configuration

[ RabbitMQ.WebUI ]
* Microsoft.AspNetCore.Mvc.Core
* Microsoft.AspNetCore.App

[ RabbitMQ.ConsumerConsole ]
* Microsoft.Extensions.DependencyInjection
* System.Configuration.ConfigurationManager

RabbitMQ Client Manage Nuget Package

RabbitMQ.Core projesinde kendi tarzımda bir klasörleme yapısı kullandım, daha farklı klasörleme ve isimlendirme kullanabilirsiniz.

RabbitMQ.Core Projesi -Klasör yapısı

RabbitMQ Konfigürasyonu için RabbitMQ Servisinin host edildiği adres, Kullanıcı Adı ve şifre bilgileri için property alanlarını tanımlıyoruz.

IRabbitMQConfiguration

Konfigürasyon bilgilerini appsettings.json dosyasından okuyacağız.

RabbitMQConfiguration

RabbitMQ için gerekli iki operasyon tanımlıyoruz.

IRabbitMQService

GetConnection metodunda Connection nesnesi oluşturabilmek için IRabbitMQConfiguration arayüzünü (Interface) constructor da alıyoruz.

RabbitMQService

IObjectConvertFormat arayüzü (Interface) üç adet metot tanımlıyoruz.

IObjectConvertFormat

RabbitMQ queue da veriyi byte[] tipinde saklamaktadır. Kuyrukta (Queue) bu veriyi gönderebilmemiz için tip dönüşümüne gerek duyarız.

ObjectConvertFormatManager

Publisher queue’ya (kuyruğa) ekleyebilmemiz için bir adet Enqueue isminde metot oluşturalım. Metot IEnumerable<T> türünde queueDataModels (List<MailMessage>) göndereceğiz ve kuyruğa (queue) yazmasını istediğimiz queueName değerini göndereceğiz.

IPublisherService

Kuyruğa (queue) yazma işlemi, bağlantı (connection) ve kanal (CreateModel) oluşturabilmek için;

PublisherManager nesnesine ait constructor da IRabbitMQService Interface’ini enjekte (inject) ediyoruz.

PublisherManager

durable: ile in-memory mi yoksa fiziksel olarak mı saklanacağı belirlenir.

exclusive: Yalnızca bir bağlantı tarafından kullanılır ve bu bağlantı kapandığında sıra silinir — özel olarak işaretlenirse silinmez

autoDelete: En son bir abonelik iptal edildiğinde en az bir müşteriye sahip olan kuyruk silinir

arguments: İsteğe bağlı; eklentiler tarafından kullanılır ve TTL mesajı, kuyruk uzunluğu sınırı, vb. özellikler tanımlanır.

RabbitMQ.WebUI projesinde Startup.cs de gerekli yapılandırma işlemlerini yapıyoruz.

RabbitMQ.WebUI-Startup

Mail gönderim için basit bir .cshtml oluşturalım.

MailSend.cshtml

Ben işlemleri HomeController da yazdım ancak gerekli iş kuralları gereği nerede yazılması gerekiyor ise o controller da yazabilirsiniz.

HomeController

Gönder butonuna tıklandığında HomeController da MailSend metodu tetiklenir. HttpPost türündedir ve metot PostMailViewModel türünde bir obje almaktadır.

Burada tanımlanan metot ismi, controller, ve viewmodel ihtiyacınıza göre değişkenlik gösterebilir.

Constructor da aldığımız IPublisherService arayüzüne (Interface) ait Enqueue metodunu tetikliyor bu metot bizden kuyruğa yazılacak objeyi ve hangi kuyruğa yazılacağının bilgisini istemektedir.

Hatırlayacak olur isek:
Enqueue<T>(IEnumerable<T> queueDataModels, string queueName)

MailSend Metodu

Enqueue metodu içerisinde gönderilecek olan mail objesinin IEnumerable<T> türünde göndereceğiz. Biz burada Mail gönderim yapabilmek için PrepareMessages isminde bir private metot tanımladık. Bu methot bize Mail gönderim işlemi için gerekli alanların set edilmesi işlemini yapacaktır.

MailMessageData
PrepareMessages metodu

Bazı sabit değişkenler ve enum tanımlamaları için RabbitMQConsts.cs ismindeki static class tanımlayalım.

RabbitMQConsts

Projede kullanılacak konfigürasyonlar için appsetting.json da alanları ayarlayalım.

RabbitMQ.WebUI içerisindeki appsetting.json dosyası

Aynı konfigürasyon işlemlerine RabbitMQ.ConsumerConsole projesinde de ihtiyaç duyarız, bu ayarlamalar için project.json da alanları ayarlayalım.

Burada dosyası console projesi (.exe) olduğu için ve exe
bin=> debug=>netcoreapp3.0 dosyası içerisinde olduğu için project.json dosyasını da exe ile aynı dizinde oluşturabiliriz.

RabbitMQ.ConsumerConsole projesine ait program.cs dosyasında gerekli konfigürasyon işlemlerini yapalım.

ConsumerConsole-Program.cs Dosyası

Consumer’i (kuyruğu dinleyen) await consumerService.Start(); ile tetikleriz ve kuyruk dinlenmeye başlar kuyrukta bekleyen iş var ise aksiyon alacaktır.

ConsumerManager.cs

Teslim alınan kuyruk işlemleri burada okunmaya ve gerekli operasyon (Mail gönderimi) tetiklemektedir.

Consumer_Received Event

kuyruğa dört adet mail gönderimi için data gönderiyoruz.

Consumer kuyruğu dinliyor ve okuduğu verilerden tanımlanan iş kurallarına göre mail gönderim işlemi yapıyor.

Ve tüm kuyruk okunmuştur.

Olası durumlarda programda RabbitMQ.ConsumerConsole uygulamasını ayrı bir proje olarak tasarladık. Queue’yu dinleyen proje kapanmış hata almış veya durmuş olsa dahi, tekrar ayağa kalktığında kaldığı yerden işlemleri devam ettirecektir.

Faydalı olmak adına yazmaya çalıştığım bir makalenin daha sonuna geldik. Umarım yararlı olmuştur.

Proje github adresi: https://github.com/ademolguner/rabbitmq_netcore_emailsend

Saygılarımla
Adem Olguner

--

--