AspNet Core’da RabbitMQ ile E-Posta Gönderim İşlemleri.
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.
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 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
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.
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.Core projesinde kendi tarzımda bir klasörleme yapısı kullandım, daha farklı klasörleme ve isimlendirme kullanabilirsiniz.
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.
Konfigürasyon bilgilerini appsettings.json dosyasından okuyacağız.
RabbitMQ için gerekli iki operasyon tanımlıyoruz.
GetConnection metodunda Connection nesnesi oluşturabilmek için IRabbitMQConfiguration arayüzünü (Interface) constructor da alıyoruz.
IObjectConvertFormat arayüzü (Interface) üç adet metot tanımlıyoruz.
RabbitMQ queue da veriyi byte[] tipinde saklamaktadır. Kuyrukta (Queue) bu veriyi gönderebilmemiz için tip dönüşümüne gerek duyarız.
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.
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.
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.
Mail gönderim için basit bir .cshtml oluşturalım.
Ben işlemleri HomeController da yazdım ancak gerekli iş kuralları gereği nerede yazılması gerekiyor ise o controller da yazabilirsiniz.
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)
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.
Bazı sabit değişkenler ve enum tanımlamaları için RabbitMQConsts.cs ismindeki static class tanımlayalım.
Projede kullanılacak konfigürasyonlar için appsetting.json da alanları ayarlayalım.
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.
Consumer’i (kuyruğu dinleyen) await consumerService.Start(); ile tetikleriz ve kuyruk dinlenmeye başlar kuyrukta bekleyen iş var ise aksiyon alacaktır.
Teslim alınan kuyruk işlemleri burada okunmaya ve gerekli operasyon (Mail gönderimi) tetiklemektedir.
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