﻿
{"id":20112,"date":"2020-12-19T22:29:01","date_gmt":"2020-12-19T22:29:01","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=20112"},"modified":"2020-12-23T22:36:17","modified_gmt":"2020-12-23T22:36:17","slug":"asp-net-core-masstransit-rabbitmq-ile-birlikte-messaging-uygulamasi","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-masstransit-rabbitmq-ile-birlikte-messaging-uygulamasi\/","title":{"rendered":"Asp.NET Core &#8211; MassTransit &#038; RabbitMQ \u0130le Birlikte Messaging Uygulamas\u0131"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bir \u00f6nceki <a href=\"https:\/\/www.gencayyildiz.com\/blog\/net-core-masstransit-kullanarak-rabbitmq-ile-messaging\/\" rel=\"noopener noreferrer\" target=\"_blank\">.NET Core \u2013 MassTransit Kullanarak RabbitMQ \u0130le Messaging<\/a> ba\u015fl\u0131kl\u0131 makalemizde MassTransit ESB k\u00fct\u00fcphanesini RabbitMQ ile birlikte ele alm\u0131\u015f ve bir\u00e7ok detay\u0131yla birlikte incelemi\u015ftik. Bu i\u00e7eri\u011fimizde ise bir senaryo dahilinde MassTransit k\u00fct\u00fcphanesi ile Asp.NET Core tabanl\u0131 bir \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftirece\u011fiz. O halde buyrun vakit kaybetmeden ba\u015flayal\u0131m&#8230;<\/p>\n<div style=\"text-align:center;\">\n<span style=\"color:purple;font-size:11px;\">Bu i\u00e7erikte kullan\u0131lacak olan MassTransit ve RabbitMQ k\u00fct\u00fcphanelerine dair temel bilgilerin bilindi\u011fi varsay\u0131lacak ve gerekmedi\u011fi taktirde ekstradan bilgilendirme yap\u0131lmayacakt\u0131r. E\u011fer varsa b\u00f6yle bir ihtiyaca istinaden \u00f6ncelikli olarak yukar\u0131da referans edilen adresteki kayna\u011f\u0131n okunmas\u0131n\u0131 tavsiye ederim.<\/span>\n<\/div>\n<h3 style=\"color:#e83e8c;\">Senaryo<\/h3>\n<p>Pratikte kodlamaya ge\u00e7meden \u00f6nce ilk olarak senaryoyu genel hatlar\u0131yla ortaya koyal\u0131m.<\/p>\n<blockquote style=\"font-size:12px;\"><p>Geli\u015ftirilen bir \u00fcr\u00fcn y\u00f6netim sisteminde a\u015fa\u011f\u0131daki ihtiya\u00e7lar\u0131n kar\u015f\u0131lanmas\u0131 gerekmektedir.<br \/>\n&#8216;ProductManagement&#8217; isminde olu\u015fturulan bir solution i\u00e7erisinde;<\/p>\n<ul>\n<li>Gelen \u00fcr\u00fcnleri kar\u015f\u0131layabilmek i\u00e7in <u><em style=\"color:blue;\">ProductManagement.Api<\/em><\/u> Web API projesi olu\u015fturulmal\u0131d\u0131r.<\/li>\n<li>\u00dcr\u00fcnleri database&#8217;e asenkron kaydedebilmek i\u00e7in <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> console uygulamas\u0131 olu\u015fturulmal\u0131d\u0131r.<\/li>\n<li>\u00dcr\u00fcnleri Facebook ve Instagram sosyal medyalar\u0131nda yay\u0131nlamak i\u00e7in <u><em style=\"color:blue;\">ProductManagement.Facebook<\/em><\/u> ve <u><em style=\"color:blue;\">ProductManagement.Instagram<\/em><\/u> console uygulamalar\u0131 olu\u015fturulmal\u0131d\u0131r.<\/li>\n<li>\u00dcr\u00fcn hakk\u0131nda m\u00fc\u015fterileri bilgilendirmek i\u00e7in <u><em style=\"color:blue;\">ProductManagement.Notification<\/em><\/u> MVC uygulamas\u0131 olu\u015fturulmal\u0131d\u0131r.<\/li>\n<li>T\u00fcm uygulamalar aras\u0131nda entegrasyonel kontraktlar\u0131 sa\u011flayacak olan(bir ba\u015fka deyi\u015fle message contract g\u00f6revini g\u00f6recek olan) <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> class library&#8217;si olu\u015ftrulmal\u0131d\u0131r. Bu library i\u00e7erisinde mesaj t\u00fcrleri, RabbitMQ hesap bilgileri, queue isimleri vs. bilgiler tutulmal\u0131d\u0131r.<\/li>\n<\/ul>\n<p>Bu ihtiya\u00e7lar kar\u015f\u0131land\u0131ktan sonra i\u015flevsel olarak \u015f\u00f6yle bir davran\u0131\u015f sergilemesi beklenmektedir; Kullan\u0131c\u0131 taraf\u0131ndan g\u00f6nderilen \u00fcr\u00fcnler <u><em style=\"color:blue;\">ProductManagement.Api<\/em><\/u> arac\u0131l\u0131\u011f\u0131yla kar\u015f\u0131lanacak ve <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> uygulamas\u0131na g\u00f6nderilecektir. <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> veritaban\u0131na kaydetti\u011fi \u00fcr\u00fcnleri biryandan da <u><em style=\"color:blue;\">ProductManagement.Facebook<\/em><\/u> ve <u><em style=\"color:blue;\">ProductManagement.Instagram<\/em><\/u> uygulamalar\u0131na g\u00f6nderecek ve b\u00f6ylece sosyal medyada yay\u0131nlam\u0131\u015f olacakt\u0131r. Ayr\u0131ca <u><em style=\"color:blue;\">ProductManagement.Notification<\/em><\/u> uygulamas\u0131na da g\u00f6ndererek m\u00fc\u015fterileri \u00fcr\u00fcnlere dair bilgilendirecektir.\n<\/p><\/blockquote>\n<h3 style=\"color:#e83e8c;\">\u0130n\u015faat<\/h3>\n<p>Her \u015feyden \u00f6nce istenilen uygulamalar\u0131 olu\u015fturarak ba\u015flayal\u0131m.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi.png\" alt=\"Asp.NET Core - MassTransit &amp; RabbitMQ \u0130le Birlikte Messaging Uygulamas\u0131\" width=\"276\" height=\"137\" class=\"aligncenter size-full wp-image-20131\" \/><\/a>Ard\u0131ndan olu\u015fturulan t\u00fcm uygulamalara <a href=\"https:\/\/www.nuget.org\/packages\/MassTransit.RabbitMQ\/\" rel=\"noopener noreferrer\" target=\"_blank\">MassTransit.RabbitMQ<\/a> k\u00fct\u00fcphanesini y\u00fckleyelim ve yan\u0131nda gerekli message contract&#8217;lar\u0131 bar\u0131nd\u0131raca\u011f\u0131 i\u00e7in <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> dll&#8217;ini referans edelim.<\/p>\n<p>Evet&#8230; San\u0131r\u0131m in\u015faat altyap\u0131s\u0131 haz\u0131r \ud83d\ude42 \u015eimdi kodlamaya ba\u015flayabiliriz.<\/p>\n<p>\u0130lk olarak <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> projesinde gerekli message contract&#8217;lar\u0131 olu\u015fturarak ba\u015flayal\u0131m. Bunun i\u00e7in ilgili library&#8217;de &#8216;RabbiMqConstants&#8217; isimli bir s\u0131n\u0131f olu\u015ftural\u0131m ve i\u00e7eri\u011fini a\u015fa\u011f\u0131dakilerle doldural\u0131m;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public static class RabbitMqConstants\r\n    {\r\n        public const string RabbitMqUri = &quot;amqps:\/\/wmfjyalu:X0GmitgZM7iXUPmT4uymccexqiTKoxJq@shark.rmq.cloudamqp.com\/wmfjyalu&quot;;\r\n        public const string Username = &quot;wmfjyalu&quot;;\r\n        public const string Password = &quot;X0GmitgZM7iXUPmT4uymccexqiTKoxJq&quot;;\r\n        public const string RegistrationServiceQueue = &quot;registration.service&quot;;\r\n        public const string NotificationServiceQueue = &quot;notification.service&quot;;\r\n        public const string FacebookServiceQueue = &quot;facebook.service&quot;;\r\n        public const string InstagramServiceQueue = &quot;instagram.service&quot;;\r\n    }\r\n<\/pre>\n<p>Bu de\u011ferler proje boyunca kullanaca\u011f\u0131m\u0131z ortak tan\u0131mlamalar, RabbitMQ credential bilgileri ve kuyruk isimleridir. Yani k\u0131saca kontratlar\u0131m\u0131zd\u0131r.<\/p>\n<p>Kontratlar\u0131n d\u0131\u015f\u0131nda bize RabbitMQ ba\u011flant\u0131l\u0131 bir bus(IBusControl) d\u00f6necek olan s\u0131n\u0131fa da ihtiyac\u0131m\u0131z olacakt\u0131r. T\u00fcm ba\u011flant\u0131lar\u0131 bu s\u0131n\u0131f \u00fczerinden ger\u00e7ekle\u015ftirecek ve y\u00f6netece\u011fiz. Dolay\u0131s\u0131yla bu i\u015flevi y\u00fcr\u00fctecek olan bu s\u0131n\u0131f\u0131 yine <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> library&#8217;sinde &#8216;BusConfigurator&#8217; isminde a\u015fa\u011f\u0131daki gibi olu\u015ftural\u0131m;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public static class BusConfigurator\r\n    {\r\n        public static IBusControl ConfigureBus(Action&lt;IRabbitMqBusFactoryConfigurator&gt; registrationAction = null)\r\n        {\r\n            return Bus.Factory.CreateUsingRabbitMq(factory =&gt;\r\n            {\r\n                factory.Host(RabbitMqConstants.RabbitMqUri, configurator =&gt;\r\n                {\r\n                    configurator.Username(RabbitMqConstants.Username);\r\n                    configurator.Password(RabbitMqConstants.Password);\r\n                });\r\n\r\n                registrationAction?.Invoke(factory);\r\n            });\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki s\u0131n\u0131fa g\u00f6z at\u0131l\u0131rsa e\u011fer, &#8216;IBusControl&#8217; t\u00fcr\u00fcnden nesne d\u00f6nd\u00fcren ve &#8216;IRabbitMqBusFactoryConfigurator&#8217; t\u00fcr\u00fcnden &#8216;registrationAction&#8217; isimli Action&#8217;\u0131 parametre olarak alan &#8216;ConfigureBus&#8217; isimli static bir metot bar\u0131nd\u0131rmaktad\u0131r. Bu metot, i\u00e7erisinde <code>Bus.Factory.CreateUsingRabbitMq<\/code> ile \u00fcretilen bir &#8216;IBusControl&#8217; nesnesini geriye d\u00f6nd\u00fcrmektedir. &#8216;registrationAction&#8217; delegasyonel parametresi ise consumer&#8217;lar taraf\u0131ndan gelen mesajlar\u0131 t\u00fcketebilmeleri i\u00e7in \u00e7a\u011fr\u0131lmas\u0131 gereken &#8216;ReceiveEndpoint&#8217; metodunu tetikleyebilmeleri i\u00e7in tan\u0131mlanm\u0131\u015ft\u0131r. Haliyle bunun i\u00e7in &#8216;IRabbitMqBusFactoryConfigurator&#8217; t\u00fcr\u00fcnden olan &#8216;factory&#8217; parametresine ihtiya\u00e7 vard\u0131r. O y\u00fczden <code>Action&lt;IRabbitMqBusFactoryConfigurator&gt;<\/code> olarak tan\u0131mlanm\u0131\u015ft\u0131r&#8230;<\/p>\n<p>Evet, art\u0131k kontratlar\u0131m\u0131z haz\u0131rlanm\u0131\u015f oldu\u011funa g\u00f6re senaryonun ilk par\u00e7as\u0131 olan ve kullan\u0131c\u0131lardan gelen \u00fcr\u00fcnleri kar\u015f\u0131layacak olan <u><em style=\"color:blue;\">ProductManagement.Api<\/em><\/u> uygulamas\u0131n\u0131 geli\u015ftirerek devam edebiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;Route(&quot;api\/&#x5B;controller]&quot;)]\r\n    &#x5B;ApiController]\r\n    public class ProductController : ControllerBase\r\n    {\r\n        &#x5B;HttpPost]\r\n        public async Task&lt;IActionResult&gt; Post(Product product)\r\n        {\r\n            \/\/\u00dcr\u00fcn kar\u015f\u0131lan\u0131r.\r\n            \/\/Gerekli \u00f6n \u00e7al\u0131\u015fmalar yap\u0131l\u0131r.\r\n\r\n            var bus = BusConfigurator.ConfigureBus();\r\n            var sendToUri = new Uri($&quot;{RabbitMqConstants.RabbitMqUri}\/{RabbitMqConstants.RegistrationServiceQueue}&quot;);\r\n            var endPoint = await bus.GetSendEndpoint(sendToUri);\r\n            await endPoint.Send&lt;IProductRegistrationCommand&gt;(product);\r\n            return Ok(&quot;G\u00f6nderdi\u011finiz \u00fcr\u00fcn taraf\u0131m\u0131za ula\u015fm\u0131\u015f ve gerekli i\u015flemler ger\u00e7ekle\u015ftirilmi\u015ftir. \u0130lginiz i\u00e7in te\u015fekk\u00fcr ederiz.&quot;);\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131da g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere kullan\u0131c\u0131 taraf\u0131ndan g\u00f6nderilen \u00fcr\u00fcnleri kar\u015f\u0131layabilmek i\u00e7in &#8216;ProductController&#8217; olu\u015fturulmu\u015ftur. Gelen &#8216;Product&#8217; nesnesini gerekli \u00f6n \u00e7al\u0131\u015fmalara tabii tuttuktan sonra veritaban\u0131na kaydedilmesi ve gerekli sosyal medyalarda yay\u0131nlayabilmesi i\u00e7in <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> projesine iletmemiz gerekmektedir. Bu durumda mesaj\u0131 iletece\u011fimiz queue belli oldu\u011fundan dolay\u0131 direkt command olarak g\u00f6ndermemiz en do\u011frusu olacakt\u0131r. Bu y\u00fczden &#8216;RegistrationServiceQueue&#8217; sabitindeki kuyruk ad\u0131na kar\u015f\u0131l\u0131k olan queue&#8217;ya gerekli &#8216;Send&#8217; operasyonu ger\u00e7ekle\u015ftirilmi\u015ftir. Burada ilgili mesaj &#8216;IProductRegistrationCommand&#8217; aray\u00fcz\u00fc e\u015fli\u011finde g\u00f6nderilmi\u015ftir. Bu aray\u00fcz\u00fc ve &#8216;Product&#8217; modelini <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> library&#8217;sinde olu\u015fturmam\u0131z, consumer olan di\u011fer uygulamalar a\u00e7\u0131s\u0131ndan da ortak eri\u015fim a\u00e7\u0131s\u0131ndan kullan\u0131\u015fl\u0131 olacakt\u0131r. Tabi siz isterseniz farkl\u0131 bir katman olu\u015fturabilir ve orada da ortak aray\u00fcz ve entity modellerinizi tutabilirsiniz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Commands\r\n{\r\n    public interface IProductRegistrationCommand\r\n    {\r\n        string ProductName { get; set; }\r\n        int Quantity { get; set; }\r\n    }\r\n}\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Models\r\n{\r\n    public class Product : IProductRegistrationCommand\r\n    {\r\n        public string ProductName { get; set; }\r\n        public int Quantity { get; set; }\r\n    }\r\n}\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-1.png\" alt=\"Asp.NET Core - MassTransit &amp; RabbitMQ \u0130le Birlikte Messaging Uygulamas\u0131\" width=\"278\" height=\"252\" class=\"alignright size-full wp-image-20150\" \/><\/a><u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> uygulamas\u0131nda ger\u00e7ekle\u015ftirilen bu tan\u0131mlamalar\u0131 yandaki g\u00f6rselde oldu\u011fu gibi uygun klas\u00f6rler i\u00e7erisinde ger\u00e7ekle\u015ftirdi\u011fimize dikkatinizi \u00e7ekerim. Command olarak iletilecek t\u00fcm mesajlar\u0131n aray\u00fczlerini &#8216;Commands&#8217; klas\u00f6r\u00fc alt\u0131nda tan\u0131mlamaktay\u0131m. Nihayetinde i\u00e7eri\u011fimizin devam\u0131nda event olarak g\u00f6nderilecek mesajlar\u0131n aray\u00fczlerinide &#8216;Events&#8217; isminde bir klas\u00f6rde tutaca\u011f\u0131z. B\u00f6ylece daha derli toplu bir in\u015fa s\u00fcreci ger\u00e7ekle\u015ftirmi\u015f olmaktay\u0131z.<\/p>\n<p>Velhas\u0131l, s\u0131ra <u><em style=\"color:blue;\">ProductManagement.Api<\/em><\/u>&#8216;dan g\u00f6nderilen mesaj\u0131 alabilmesi i\u00e7in <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> uygulamas\u0131n\u0131 geli\u015ftirmeye gelmi\u015ftir. \u0130lgili uygulaman\u0131n &#8216;Program.cs&#8217; dosyas\u0131nda a\u015fa\u011f\u0131daki \u00e7al\u0131\u015fman\u0131n yap\u0131lmas\u0131 gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.Registration\r\n{\r\n    class Program\r\n    {\r\n        static async Task Main(string&#x5B;] args)\r\n        {\r\n            var bus = BusConfigurator.ConfigureBus(factory =&gt;\r\n            {\r\n                factory.ReceiveEndpoint(RabbitMqConstants.RegistrationServiceQueue, endpoint =&gt;\r\n                {\r\n                    endpoint.Consumer&lt;ProductRegistrationCommandConsumer&gt;();\r\n                });\r\n            });\r\n\r\n            await bus.StartAsync();\r\n            await Task.Run(() =&gt; Console.ReadLine());\r\n            await bus.StopAsync();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>Yukar\u0131da g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> uygulamas\u0131 direkt olarak &#8216;RegistrationServiceQueue&#8217; sabitine kar\u015f\u0131l\u0131k olan kuyru\u011fu dinlemekte ve &#8216;ProductRegistrationCommandConsumer&#8217; t\u00fcr\u00fcnden t\u00fcketim ger\u00e7ekle\u015ftirmektedir. &#8216;ProductRegistrationCommandConsumer&#8217; i\u00e7eri\u011fine g\u00f6z atarsak e\u011fer;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Consumers\r\n{\r\n    public class ProductRegistrationCommandConsumer : IConsumer&lt;IProductRegistrationCommand&gt;\r\n    {\r\n        public async Task Consume(ConsumeContext&lt;IProductRegistrationCommand&gt; context)\r\n        {\r\n            Console.WriteLine($&quot;{context.Message.ProductName} isimli \u00fcr\u00fcn :&quot;);\r\n            Console.WriteLine($&quot;Veritaban\u0131na kay\u0131t edilmi\u015ftir.&quot;);\r\n            Console.WriteLine($&quot;Facebook'ta yay\u0131nlanacakt\u0131r.&quot;);\r\n            Console.WriteLine($&quot;Instagram'da yay\u0131nlanacakt\u0131r.&quot;);\r\n            Console.WriteLine(&quot;*********************&quot;);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-2.png\" alt=\"Asp.NET Core - MassTransit &amp; RabbitMQ \u0130le Birlikte Messaging Uygulamas\u0131\" width=\"315\" height=\"292\" class=\"alignright size-full wp-image-20157\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-2.png 315w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-2-300x278.png 300w\" sizes=\"auto, (max-width: 315px) 100vw, 315px\" \/><\/a><u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> library&#8217;sinde tan\u0131mlad\u0131\u011f\u0131m\u0131z &#8216;IProductRegistrationCommand&#8217; t\u00fcr\u00fcnden gelen mesajlar\u0131 yakalamaktad\u0131r.<\/p>\n<p>Bu ve bunun gibi s\u00fcre\u00e7te tan\u0131mlayaca\u011f\u0131m\u0131z t\u00fcm consumer s\u0131n\u0131flar\u0131n\u0131 <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> library&#8217;sin de proje nizam\u0131n\u0131 koruyabilmek i\u00e7in yandaki g\u00f6rselde oldu\u011fu gibi &#8216;Consumers&#8217; klas\u00f6r\u00fc alt\u0131nda toplayaca\u011f\u0131m\u0131z\u0131 bilmenizde fayda var.<\/p>\n<p>Bu \u00e7al\u0131\u015fma neticesinde <u><em style=\"color:blue;\">ProductManagement.Api<\/em><\/u> ile <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> uygulamalar\u0131 aras\u0131nda MassTransit ve RabbitMQ ile gerekli ba\u011flant\u0131 sa\u011flanm\u0131\u015f bulunmaktad\u0131r. Dilerseniz devam etmeden \u00f6nce bu uygulamalar\u0131n senkronizasyonunu test edelim ve \u00e7al\u0131\u015fmam\u0131z\u0131n bu noktaya kadar olan i\u015flevlerinden emin olal\u0131m.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi.gif\" alt=\"Asp.NET Core - MassTransit &amp; RabbitMQ \u0130le Birlikte Messaging Uygulamas\u0131\" width=\"800\" height=\"885\" class=\"aligncenter size-full wp-image-20163\" \/><\/a><br \/>\nS\u00fcper \ud83d\ude42 Yukar\u0131daki ekran g\u00f6r\u00fcnt\u00fcs\u00fcnde oldu\u011fu gibi Postman arac\u0131l\u0131\u011f\u0131yla g\u00f6nderilen datan\u0131n API taraf\u0131ndan kar\u015f\u0131land\u0131ktan sonra ilgili uygulamaya mesaj tabanl\u0131 iletildi\u011fini g\u00f6zlemlemekteyiz.<\/p>\n<p>\u0130n\u015faata devam edersek e\u011fer <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> uygulamas\u0131 taraf\u0131ndan elde edilen mesaj\u0131 sosyal medyalarda yay\u0131nlayabilmek i\u00e7in ilgili <u><em style=\"color:blue;\">ProductManagement.Facebook<\/em><\/u> ve <u><em style=\"color:blue;\">ProductManagement.Instagram<\/em><\/u> uygulamalar\u0131na ve m\u00fc\u015fterileri \u00fcr\u00fcne dair bilgilendirmek i\u00e7inde <u><em style=\"color:blue;\">ProductManagement.Notification<\/em><\/u> uygulamas\u0131na g\u00f6ndermeliyiz. Haliyle birden fazla uygulama sadece kendilerine ait kuyruklardan bu mesajlar\u0131 edinece\u011finden dolay\u0131 burada ilgili mesaj\u0131 event olarak t\u00fcm kuyruklara iletmemiz yerinde olacakt\u0131r. Yani ilgili mesaj t\u00fcm kuyruklara publish edilecektir.<\/p>\n<p>Bunun i\u00e7in <u><em style=\"color:blue;\">ProductManagement.Registration<\/em><\/u> uygulamas\u0131n\u0131n api taraf\u0131ndan iletilen mesaj\u0131 kar\u015f\u0131lad\u0131\u011f\u0131 &#8216;ProductRegistrationCommandConsumer&#8217; i\u00e7erisinde \u00e7al\u0131\u015fmam\u0131z gerekmektedir. \u00c7\u00fcnk\u00fc bu s\u0131n\u0131f, gelen mesaj\u0131 yakalad\u0131ktan sonra ihtiyac\u0131 olan di\u011fer kuyruklara publish edebilmemiz i\u00e7in bize f\u0131rsat tan\u0131maktad\u0131r.<\/p>\n<p>\u0130lgili s\u0131n\u0131f\u0131n son hali a\u015fa\u011f\u0131daki gibi olacakt\u0131r;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Consumers\r\n{\r\n    public class ProductRegistrationCommandConsumer : IConsumer&lt;IProductRegistrationCommand&gt;\r\n    {\r\n        public async Task Consume(ConsumeContext&lt;IProductRegistrationCommand&gt; context)\r\n        {\r\n            Console.WriteLine($&quot;{context.Message.ProductName} isimli \u00fcr\u00fcn :&quot;);\r\n            Console.WriteLine($&quot;Veritaban\u0131na kay\u0131t edilmi\u015ftir.&quot;);\r\n            Console.WriteLine($&quot;Facebook'ta yay\u0131nlanacakt\u0131r.&quot;);\r\n            Console.WriteLine($&quot;Instagram'da yay\u0131nlanacakt\u0131r.&quot;);\r\n            Console.WriteLine(&quot;*********************&quot;);\r\n\r\n            await context.Publish&lt;IProductEvent&gt;(new Product\r\n            {\r\n                ProductName = context.Message.ProductName,\r\n                Quantity = context.Message.Quantity\r\n            });\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere api&#8217;den gelen mesaj\u0131 t\u00fcm kuyruklara publish etmekteyiz. Dikkat ederseniz publish edilen mesaj\u0131 &#8216;IProductEvent&#8217; aray\u00fcz\u00fcnden g\u00f6ndermekteyiz. \u0130lgili aray\u00fcz\u00fc <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> library&#8217;sinde a\u015fa\u011f\u0131daki gibi &#8216;Events&#8217; isimli bir klas\u00f6r alt\u0131nda olu\u015fturmaktay\u0131z.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Events\r\n{\r\n    public interface IProductEvent\r\n    {\r\n        string ProductName { get; set; }\r\n        int Quantity { get; set; }\r\n    }\r\n}\r\n<\/pre>\n<p>Tabi &#8216;Product&#8217; modelini de bu aray\u00fcz e\u015fli\u011finde publish edebilmek i\u00e7in ilgili aray\u00fczden implement etmeyi unutmuyoruz:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public class Product : IProductRegistrationCommand, IProductEvent\r\n    {\r\n        public string ProductName { get; set; }\r\n        public int Quantity { get; set; }\r\n    }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-3-288x300.png\" alt=\"Asp.NET Core - MassTransit &amp; RabbitMQ \u0130le Birlikte Messaging Uygulamas\u0131\" width=\"288\" height=\"300\" class=\"alignleft size-medium wp-image-20180\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-3-288x300.png 288w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-3.png 316w\" sizes=\"auto, (max-width: 288px) 100vw, 288px\" \/><\/a>Bu i\u015flemlerden sonra <u><em style=\"color:blue;\">ProductManagement.MessageContracts<\/em><\/u> library&#8217;sinin son hali yandaki gibi olacakt\u0131r. Art\u0131k bu a\u015famadan sonra publish edilen mesajlar\u0131 ilgili uygulamalarda consume edebilmek i\u00e7in gerekli consumer s\u0131n\u0131flar\u0131n\u0131 olu\u015fturacak ve ard\u0131ndan uygulamalarda ilgili kuyruklar\u0131 t\u00fcketece\u011fiz.<\/p>\n<p>\u015eimdi gelin s\u0131ras\u0131yla Facebook, Instagram ve Notification consumer&#8217;lar\u0131n\u0131 olu\u015ftural\u0131m ve ard\u0131ndan ilgili uygulamalar\u0131 kodlamaya ge\u00e7elim.<br \/>&nbsp;<br \/>&nbsp;<br \/>\n&#8216;Facebook&#8217; :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Consumers\r\n{\r\n    public class ProductFacebookEventConsumer : IConsumer&lt;IProductEvent&gt;\r\n    {\r\n        public async Task Consume(ConsumeContext&lt;IProductEvent&gt; context)\r\n        {\r\n            Console.WriteLine($&quot;{context.Message.ProductName} isimli \u00fcr\u00fcn Facebook'ta yay\u0131nlanm\u0131\u015ft\u0131r.&quot;);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>&#8216;Instagram&#8217; :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Consumers\r\n{\r\n    public class ProductInstagramEventConsumer : IConsumer&lt;IProductEvent&gt;\r\n    {\r\n        public async Task Consume(ConsumeContext&lt;IProductEvent&gt; context)\r\n        {\r\n            Console.WriteLine($&quot;{context.Message.ProductName} isimli \u00fcr\u00fcn Instagram'da yay\u0131nlanm\u0131\u015ft\u0131r.&quot;);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>&#8216;Notification&#8217; :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.MessageContracts.Consumers\r\n{\r\n    public class ProductNotificationEventConsumer : IConsumer&lt;IProductEvent&gt;\r\n    {\r\n        public async Task Consume(ConsumeContext&lt;IProductEvent&gt; context)\r\n        {\r\n            Console.WriteLine($&quot;{context.Message.ProductName} isimli \u00fcr\u00fcn yay\u0131nlanarak m\u00fc\u015fteriler bilgilendirilmi\u015ftir.&quot;);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>Consumer&#8217;lar haz\u0131r. \u015eimdi s\u0131rada, uygulamalar \u00fczerinden ilgili consumer&#8217;lar\u0131 kullanarak kuyruklardaki mesajlar\u0131 t\u00fcketmek var.<br \/>\n&#8216;Facebook&#8217; :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.Facebook\r\n{\r\n    class Program\r\n    {\r\n        static async Task Main(string&#x5B;] args)\r\n        {\r\n            var bus = BusConfigurator.ConfigureBus(factory =&gt;\r\n            {\r\n                factory.ReceiveEndpoint(RabbitMqConstants.FacebookServiceQueue, endpoint =&gt;\r\n                {\r\n                    endpoint.Consumer&lt;ProductFacebookEventConsumer&gt;();\r\n                });\r\n            });\r\n\r\n            await bus.StartAsync();\r\n            await Task.Run(() =&gt; Console.ReadLine());\r\n            await bus.StopAsync();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>&#8216;Instagram&#8217; :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.Instagram\r\n{\r\n    class Program\r\n    {\r\n        static async Task Main(string&#x5B;] args)\r\n        {\r\n            var bus = BusConfigurator.ConfigureBus(factory =&gt;\r\n            {\r\n                factory.ReceiveEndpoint(RabbitMqConstants.FacebookServiceQueue, endpoint =&gt;\r\n                {\r\n                    endpoint.Consumer&lt;ProductInstagramEventConsumer&gt;();\r\n                });\r\n            });\r\n\r\n            await bus.StartAsync();\r\n            await Task.Run(() =&gt; Console.ReadLine());\r\n            await bus.StopAsync();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>&#8216;Notification&#8217; :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnamespace ProductManagement.Notification.Controllers\r\n{\r\n    public class ProductNotificationController : Controller\r\n    {\r\n        public async Task&lt;IActionResult&gt; Index()\r\n        {\r\n\r\n            var bus = BusConfigurator.ConfigureBus(factory =&gt;\r\n            {\r\n                factory.ReceiveEndpoint(RabbitMqConstants.NotificationServiceQueue, endpoint =&gt;\r\n                {\r\n                    endpoint.Consumer&lt;ProductNotificationEventConsumer&gt;();\r\n                });\r\n            });\r\n\r\n            await bus.StartAsync();\r\n            await Task.Run(() =&gt; Console.ReadLine());\r\n            await bus.StopAsync();\r\n            return View();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>\u0130\u015fte bu kadar&#8230; T\u00fcm bu in\u015fa s\u00fcrecinden sonra t\u00fcm uygulamalar\u0131 derleyip, \u00e7al\u0131\u015ft\u0131ral\u0131m ve test edelim.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-1.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Asp.NET-Core-MassTransit-RabbitMQ-Ile-Birlikte-Messaging-Uygulamasi-1.gif\" alt=\"Asp.NET Core - MassTransit &amp; RabbitMQ \u0130le Birlikte Messaging Uygulamas\u0131\" width=\"800\" height=\"462\" class=\"aligncenter size-full wp-image-20194\" \/><\/a><\/p>\n<p>Veee g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere uygulamalar\u0131m\u0131z MassTransit sayesinde tam teferruatl\u0131 mesaj tabanl\u0131 ileti\u015fimi ger\u00e7ekle\u015ftirebilmektedir.<\/p>\n<p>Makalemizi sonland\u0131rmadan \u00f6nce web uygulamas\u0131 olan <u><em style=\"color:blue;\">ProductManagement.Notification<\/em><\/u> projesinde gelen verileri anl\u0131k olarak sayfada g\u00f6sterebilmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-signalr-yazi-serisi\/\" rel=\"noopener noreferrer\" target=\"_blank\">SignalR<\/a> teknolojisinden istifade edebiliriz diye d\u00fc\u015f\u00fcnd\u00fcm. Ve bununla ilgili gerekli \u00e7al\u0131\u015fmay\u0131 makalemizin sonunda sunmu\u015f oldu\u011fum \u00f6rnek \u00e7al\u0131\u015fma projesinde uygulam\u0131\u015f bulunmaktay\u0131m. \u0130ndirmenizi ve incelemenizi tavsiye ederim \ud83d\ude42<\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek projeyi indirmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/ProductManagement.zip\">buraya<\/a> t\u0131klay\u0131n\u0131z.<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bir \u00f6nceki .NET Core \u2013 MassTransit Kullanarak RabbitMQ \u0130le Messaging ba\u015fl\u0131kl\u0131 makalemizde MassTransit ESB k\u00fct\u00fcphanesini RabbitMQ ile birlikte ele alm\u0131\u015f ve bir\u00e7ok detay\u0131yla birlikte incelemi\u015ftik. Bu i\u00e7eri\u011fimizde ise bir senaryo dahilinde MassTransit k\u00fct\u00fcphanesi&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":20110,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,3573,3156],"tags":[4025,4018,4024,4019,3575,3158],"class_list":["post-20112","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-microservices","category-rabbitmq","tag-asp-net-core-masstransit","tag-masstransit","tag-masstransit-ornek-uygulama","tag-masstransit-rabbitmq","tag-microservice","tag-rabbitmq"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20112","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=20112"}],"version-history":[{"count":77,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20112\/revisions"}],"predecessor-version":[{"id":20200,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/20112\/revisions\/20200"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/20110"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=20112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=20112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=20112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}