﻿
{"id":22040,"date":"2021-06-13T21:54:40","date_gmt":"2021-06-13T21:54:40","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=22040"},"modified":"2021-06-13T21:54:40","modified_gmt":"2021-06-13T21:54:40","slug":"asp-net-core-mongodb-event-store-ile-event-sourcing-read-data-store-uygulamasiorneklendirme","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-mongodb-event-store-ile-event-sourcing-read-data-store-uygulamasiorneklendirme\/","title":{"rendered":"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>\u00d6nceki <a href=\"https:\/\/www.gencayyildiz.com\/blog\/asp-net-core-event-store-ile-event-sourcing-uygulamasiorneklendirme\/\" rel=\"noopener\" target=\"_blank\">Asp.NET Core + Event Store \u0130le Event Sourcing Uygulamas\u0131(\u00d6rneklendirme)<\/a> ba\u015fl\u0131kl\u0131 yaz\u0131mda bir veri \u00fczerinde yap\u0131lan t\u00fcm i\u015flemleri Event Store tool&#8217;u ile kay\u0131t alt\u0131na alm\u0131\u015f ve b\u00f6ylece Event Sourcing&#8217;in <em>Write Data Store<\/em> kanad\u0131n\u0131 tamamlam\u0131\u015ft\u0131k. Bu i\u00e7eri\u011fimizde ise ilgili verilere dair sorgulama ihtiya\u00e7lar\u0131na istinaden Event Store tool&#8217;undaki event&#8217;leri \u015fartl\u0131 sorgulayamad\u0131\u011f\u0131m\u0131zdan\/sorgulayamayaca\u011f\u0131m\u0131zdan dolay\u0131 Event Sourcing&#8217;in <em>Read Data Store<\/em> k\u0131sm\u0131yla ilgilenecek ve gelen event&#8217;lerin bir b\u00fct\u00fcn\u00fc temsil edecek \u015fekilde sadece read i\u015flemleri i\u00e7in herhangi bir veritaban\u0131na kaydedilmesini ve i\u015flenmesini sa\u011flam\u0131\u015f olaca\u011f\u0131z. Bu veritaban\u0131 relational olabilece\u011fi gibi NoSQL bir yakla\u015f\u0131m\u0131 da benimsemi\u015f herhangi bir teknoloji olabilecektir. Bizler bu i\u00e7eri\u011fimizde MongoDB \u00fczerinden \u00f6rneklendirme yap\u0131yor olaca\u011f\u0131z. Anlayaca\u011f\u0131n\u0131z g\u00fczel ve heyecanl\u0131 bir serinin devam\u0131 niteli\u011finde olacak bu i\u00e7eri\u011fimiz, sizlerde ya\u015fatt\u0131\u011f\u0131 kadar bende de heyecan yaratmakta oldu\u011fu i\u00e7in hi\u00e7 vakit kaybetmeden konuya giri\u015f yapal\u0131m istiyorum&#8230;<\/p>\n<h3>Ba\u015flarken<\/h3>\n<p><div id=\"attachment_22053\" style=\"width: 326px\" class=\"wp-caption alignleft\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-22053\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"316\" height=\"220\" class=\"size-full wp-image-22053\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme.png 316w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-300x209.png 300w\" sizes=\"auto, (max-width: 316px) 100vw, 316px\" \/><\/a><p id=\"caption-attachment-22053\" class=\"wp-caption-text\">Yap\u0131lan de\u011fi\u015fiklik neticesinde eklenen Shared katman\u0131&#8230;<\/p><\/div>\u0130lk olarak, yukar\u0131da konuyla alakal\u0131 olarak referans etti\u011fim ilgili makalede sunulan mimaride ufakta olsa bir de\u011fi\u015fiklik yaparak ba\u015flamak istiyorum. Bu de\u011fi\u015fiklik, bu i\u00e7eri\u011fimizde uygulayaca\u011f\u0131m\u0131z Read Data Store operasyonunun sorumlulu\u011funu s\u0131radan bir Console uygulamas\u0131na verece\u011fimizden kaynaklanmaktad\u0131r. Bu console uygulamas\u0131, Event Store&#8217;a i\u015flenen herhangi bir event durumunda subscribe olunan messaging \u00fczerinden tetiklenecek ve veritaban\u0131nda ilgili data&#8217;ya dair create, update yahut delete operasyonlar\u0131n\u0131 ger\u00e7ekle\u015ftirecektir. Haliyle \u00f6nceki yaz\u0131da sunulan Model ve Event Type class&#8217;lar\u0131n\u0131n bu console uygulamas\u0131ndan eri\u015filebilir olmas\u0131 gerekecektir. Haliyle mimaride bahsedilen class&#8217;lar\u0131 her iki uygulamadan da eri\u015filebilir hale getirebilmek i\u00e7in &#8216;Shared&#8217; isimli class library&#8217;e alm\u0131\u015f ve di\u011fer iki uygulama taraf\u0131ndan referans etmi\u015f bulunmaktay\u0131m. Yap\u0131lan de\u011fi\u015fiklikleri daha net anlayabilmek i\u00e7in i\u00e7eri\u011fimizin sonunda payla\u015fm\u0131\u015f oldu\u011fum projenin son halini indirip fiziksel g\u00f6zlem yapabilirsiniz.<\/p>\n<h6>MongoDB.Driver ve EventStore.ClientAPI K\u00fct\u00fcphanelerinin Y\u00fcklenmesi ve Temel Konfig\u00fcrasyonlar<\/h6>\n<p>\u0130lk olarak Read Data Store operasyonunu y\u00fcr\u00fctecek olan Console uygulamam\u0131zda MongoDB ve Event Store i\u015flemlerinin y\u00fcr\u00fct\u00fclebilmesi i\u00e7in s\u0131ras\u0131yla <a href=\"https:\/\/www.nuget.org\/packages\/mongodb.driver\" rel=\"noopener\" target=\"_blank\">MongoDB.Driver<\/a> ve <a href=\"https:\/\/www.nuget.org\/packages\/EventStore.Client\/\" rel=\"noopener\" target=\"_blank\">EventStore.Client<\/a> k\u00fct\u00fcphanelerinin y\u00fcklenmesi gerekmektedir.<\/p>\n<p>Ard\u0131ndan her iki sunucuyla ilgili konfig\u00fcrasyonlar\u0131 a\u015fa\u011f\u0131daki gibi ger\u00e7ekle\u015ftirelim;<\/p>\n<p>MongoDBConfiguration:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    static public class MongoDBConfiguration\r\n    {\r\n        static IMongoDatabase database;\r\n        public static void GetDatabase()\r\n        {\r\n            if (database == null)\r\n            {\r\n                MongoClient mongoClient = new(&quot;mongodb:\/\/localhost:27017&quot;);\r\n                database = mongoClient.GetDatabase(&quot;EventStoreReadDB&quot;);\r\n            }\r\n        }\r\n        public static IMongoCollection&lt;T&gt; Collection&lt;T&gt;(string collectionName)\r\n        {\r\n            GetDatabase();\r\n            IMongoCollection&lt;T&gt; collection = database.GetCollection&lt;T&gt;(collectionName);\r\n            return collection;\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer &#8216;GetDatabase&#8217; metodu i\u00e7erisinde veritaban\u0131 yoksa olu\u015fturulmakta ard\u0131ndan &#8216;Collection&#8217; metodu i\u00e7erisinde ise parametre de\u011ferine uygun collection geriye d\u00f6n\u00fclmektedir.<\/p>\n<p>EventStoreConfiguration: <\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    public static class EventStoreConfiguration\r\n    {\r\n        public static async Task&lt;IEventStoreConnection&gt; Connect()\r\n        {\r\n            IEventStoreConnection connection = EventStoreConnection.Create(\r\n              connectionString: &quot;ConnectTo=tcp:\/\/localhost:1115;DefaultUserCredentials=admin:changeit;UseSslConnection=true;TargetHost=eventstore.org;ValidateServer=false&quot;,\r\n              connectionName: &quot;Console_Application&quot;,\r\n              builder: ConnectionSettings.Create().KeepReconnecting()\r\n             );\r\n\r\n            await connection.ConnectAsync();\r\n            connection.Connected += (object sender, ClientConnectionEventArgs e) =&gt; Console.WriteLine(&quot;Event Store dinlenmektedir...&quot;);\r\n            return connection;\r\n        }\r\n    }\r\n<\/pre>\n<p>Bu kod blo\u011funda ise Event Store&#8217;a ba\u011flant\u0131 sa\u011flam\u0131\u015f olan bir connection yarat\u0131lmaktad\u0131r.<\/p>\n<h6>Read Data Store&#8217;a Event&#8217;lerin \u0130\u015flenmesi<\/h6>\n<p>Event Store&#8217;a event eklendik\u00e7e Read Data Store veritaban\u0131ndaki(MongoDB) ilgili veriye bu event&#8217;leri i\u015fleyebilmek i\u00e7in yukar\u0131da olu\u015fturulmu\u015f olan &#8216;EventStoreConfiguration&#8217; konfig\u00fcrasyonundaki connection&#8217;a a\u015fa\u011f\u0131daki extension metodun yaz\u0131lmas\u0131 \u00e7\u00f6z\u00fcmlerden biri olacakt\u0131r:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    static public class StreamSubscriber\r\n    {\r\n        public static async Task UserSubscribe(this IEventStoreConnection connection, IMongoCollection&lt;User&gt; userCollection)\r\n        {\r\n            await connection.SubscribeToAllAsync(\r\n                resolveLinkTos: true,\r\n                eventAppeared: async (eventStoreSubscription, resolvedEvent) =&gt;\r\n                {\r\n                    \/\/Return Type class'\u0131 farkl\u0131 bir class library ya da proje de ise bu \u015fekilde metinsel olarak nitelendirilip\r\n                    \/\/Type.GetType(...)'a verilmelidir.\r\n                    var returnType = $&quot;{Encoding.UTF8.GetString(resolvedEvent.Event.Metadata)}, Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&quot;;\r\n                    Type eventType = Type.GetType(returnType);\r\n                    object @event = JsonSerializer.Deserialize(Encoding.UTF8.GetString(resolvedEvent.Event.Data), eventType);\r\n\r\n                    User user = null;\r\n                    UpdateDefinition&lt;User&gt; update = null;\r\n                    switch (@event)\r\n                    {\r\n                        case UserCreated o:\r\n                            \/\/User'\u0131 veritaban\u0131na ekle\r\n                            user = new()\r\n                            {\r\n                                Id = o.UserId,\r\n                                Email = o.Email,\r\n                                EmailApprove = o.EmailApprove,\r\n                                Name = o.Name,\r\n                                UserName = o.UserName\r\n                            };\r\n                            await userCollection.InsertOneAsync(user);\r\n                            break;\r\n                        case UserNameChanged o:\r\n                            \/\/User'\u0131 veritaban\u0131ndan \u00e7ek ve ad\u0131n\u0131 g\u00fcncelle\r\n                            update = Builders&lt;User&gt;.Update.Set(u =&gt; u.Name, o.NewName);\r\n                            await userCollection.UpdateOneAsync(f =&gt; f.Id == o.UserId, update);\r\n                            break;\r\n                        case UserEmailApproved o:\r\n                            \/\/User'\u0131 veritaban\u0131ndan \u00e7ek ve email'i onayla\r\n                            update = Builders&lt;User&gt;.Update.Set(u =&gt; u.EmailApprove, true);\r\n                            await userCollection.UpdateOneAsync(f =&gt; f.Id == o.UserId, update);\r\n                            break;\r\n                    }\r\n\r\n                },\r\n                subscriptionDropped: (eventStoreSubscription, subscriptionDropReason, exception) =&gt; Console.WriteLine($&quot;Ba\u011flant\u0131 kopmu\u015ftur. {subscriptionDropReason}&quot;)\r\n                );\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kodun izah\u0131n\u0131 yapmam\u0131z gerekirse e\u011fer &#8216;UserSubscribe&#8217; metodu i\u00e7erisindeki <strong><em>5.<\/em><\/strong> sat\u0131rda \u00e7a\u011fr\u0131lan <code style=\"color:red;font-size:13px;\">SubscribeToAllAsync<\/code> metodu e\u015fli\u011finde Event Store&#8217;da ki t\u00fcm stream&#8217;lere subscribe olunmaktad\u0131r. <strong><em>11<\/em><\/strong> ile <strong><em>13.<\/em><\/strong> sat\u0131r aral\u0131\u011f\u0131nda o anda JSON olarak eklenen event&#8217;in hangi t\u00fcrde(EventType) oldu\u011fu Metadata bilgisinden edinilerek o t\u00fcr bir object&#8217;e d\u00f6n\u00fc\u015ft\u00fcr\u00fclme i\u015flemleri ger\u00e7ekle\u015ftirilmektedir.<span style=\"font-size:9px;\">(\u00c7\u00fcnk\u00fc \u00f6nceki makalede bu bilgiyi ilgili event&#8217;in Metadata&#8217;s\u0131na biz koymu\u015ftuk)<\/span> <strong><em>17<\/em><\/strong> ile <strong><em>41.<\/em><\/strong> sat\u0131r aral\u0131\u011f\u0131nda ise ilgili event&#8217;in hangi t\u00fcrde oldu\u011fu tespit edilerek gerekli i\u015flemler ger\u00e7ekle\u015ftirilmektedir. Misal; e\u011fer event t\u00fcr\u00fc <code>UserCreated<\/code> ise &#8216;userCollection&#8217;a ekleme i\u015flemi ger\u00e7ekle\u015ftirilmekte, yok e\u011fer <code>UserNameChanged<\/code> ise ilgili data elde edilip ad\u0131 de\u011fi\u015ftirilmekte yahut <code>UserEmailApproved<\/code> ise yine ilgili data elde edilerek bu seferde email onay\u0131 verilmektedir.<\/p>\n<p>Fark\u0131ndaysan\u0131z e\u011fer, Event Sourcing operasyonunda Write Data Store&#8217;a eklenen event her neyse bunun Read Data Store&#8217;a yans\u0131mas\u0131 Metadata \u00fczerinden ta\u015f\u0131nan class t\u00fcr\u00fc bilgisiyle sa\u011flanmaktad\u0131r. Bunun i\u00e7in yaz\u0131m\u0131z\u0131n ba\u015f\u0131nda bahsedilen &#8216;Shared&#8217; isimli katman olu\u015fturularak ilgili class&#8217;lar\u0131n her iki data store&#8217;u besleyen uygulama taraflar\u0131ndan eri\u015filebilir olmas\u0131 sa\u011flanm\u0131\u015ft\u0131r. Hatta <strong><em>11.<\/em><\/strong> sat\u0131ra g\u00f6z atarsan\u0131z, farkl\u0131 bir projede ki class&#8217;\u0131n object&#8217;ini deserialize i\u015flemi ile elde etmek icap etti\u011finde bir tek class&#8217;\u0131n fullname de\u011feri yeterli olmamakta ayr\u0131ca yan\u0131na <u><em style=\"color:orange;font-size:14px;\"><span style=\"color:#D2691E;\">{Class Name}<\/span>, Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null<\/em><\/u> bilgisinin de eklenmesi gerekmektedir. Bu da bu tarz durumlar i\u00e7in ayr\u0131 bir genel k\u00fclt\u00fcr mahiyetinde bilgidir.<\/p>\n<h6>Program.cs&#8217;in Yap\u0131land\u0131r\u0131lmas\u0131<\/h6>\n<p>T\u00fcm bu yap\u0131lan konfig\u00fcrasyonlar ve abonelikler neticesinde console uygulamas\u0131ndaki &#8216;Program.cs&#8217; dosyas\u0131n\u0131n i\u00e7eri\u011fi a\u015fa\u011f\u0131daki gibi olacakt\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static async Task Main(string&#x5B;] args)\r\n        {\r\n            IEventStoreConnection connection = await EventStoreConfiguration.Connect();\r\n\r\n            IMongoCollection&lt;User&gt; userCollection = MongoDBConfiguration.Collection&lt;User&gt;(&quot;users&quot;);\r\n\r\n            await connection.UserSubscribe(userCollection);\r\n\r\n            Console.Read();\r\n        }\r\n    }\r\n<\/pre>\n<h6>Test Edelim<\/h6>\n<p>\u015eimdi yapt\u0131\u011f\u0131m\u0131z bu \u00e7al\u0131\u015fmalar neticesinde event sourcing yap\u0131lanmas\u0131n\u0131 test edelim.<\/p>\n<ul>\n<li><strong><em>Test Ad\u0131m\u0131 1 :<\/em><\/strong> <em style=\"color:green;\">Kullan\u0131c\u0131 ekleme(UserCreated)<\/em><br \/>\n<table>\n<thead>\n<tr>\n<th width=\"50%\">Request<\/th>\n<th>Read Data Store<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-1.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"702\" height=\"266\" class=\"aligncenter size-full wp-image-22078\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-1.png 702w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-1-300x114.png 300w\" sizes=\"auto, (max-width: 702px) 100vw, 702px\" \/><\/a><\/td>\n<td><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-2.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"509\" height=\"166\" class=\"aligncenter size-full wp-image-22079\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-2.png 509w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-2-300x98.png 300w\" sizes=\"auto, (max-width: 509px) 100vw, 509px\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li><strong><em>Test Ad\u0131m\u0131 2 :<\/em><\/strong> <em style=\"color:green;\">Kullan\u0131c\u0131 ad\u0131n\u0131 de\u011fi\u015ftirme(UserNameChanged)<\/em><br \/>\n<table>\n<thead>\n<tr>\n<th width=\"50%\">Request<\/th>\n<th>Read Data Store<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-3.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"726\" height=\"242\" class=\"aligncenter size-full wp-image-22083\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-3.png 726w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-3-300x100.png 300w\" sizes=\"auto, (max-width: 726px) 100vw, 726px\" \/><\/a><\/td>\n<td><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-4.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"510\" height=\"166\" class=\"aligncenter size-full wp-image-22084\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-4.png 510w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-4-300x98.png 300w\" sizes=\"auto, (max-width: 510px) 100vw, 510px\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<li><strong><em>Test Ad\u0131m\u0131 3 :<\/em><\/strong> <em style=\"color:green;\">Kullan\u0131c\u0131 e-mail&#8217;ini onaylama(UserEmailApproved)<\/em><br \/>\n<table>\n<thead>\n<tr>\n<th width=\"50%\">Request<\/th>\n<th>Read Data Store<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-5.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"726\" height=\"222\" class=\"aligncenter size-full wp-image-22086\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-5.png 726w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-5-300x92.png 300w\" sizes=\"auto, (max-width: 726px) 100vw, 726px\" \/><\/a><\/td>\n<td><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-6.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"507\" height=\"162\" class=\"aligncenter size-full wp-image-22087\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-6.png 507w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-6-300x96.png 300w\" sizes=\"auto, (max-width: 507px) 100vw, 507px\" \/><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/li>\n<\/ul>\n<p>Evet&#8230; G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Event Store&#8217;da ki t\u00fcm event&#8217;lere kar\u015f\u0131l\u0131k ilgili data \u00fczerinde gerekli i\u015flemler ger\u00e7ekle\u015ftirilmi\u015f ve b\u00f6ylece event sourcing pattern&#8217;\u0131n\u0131n bizlere sundu\u011fu tasar\u0131m uygulanm\u0131\u015ft\u0131r. Haliyle art\u0131k nihai olarak verilerimiz salt bir de\u011ferden ziyade olaylar zincirinin bir b\u00fct\u00fcn olarak bir araya gelmesiyle daha geni\u015f anlam kazanmakta ve ihtiya\u00e7 do\u011frultusunda bu anlam\u0131 g\u00f6zlemleyebilmek i\u00e7in event store tool&#8217;undan ilgili dataya \u00f6zel bir sorgulama ile data&#8217;n\u0131n ya\u015fam s\u00fcrecini seyredebilmekteyiz.<\/p>\n<div id=\"attachment_22089\" style=\"width: 439px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-7.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-22089\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-7.png\" alt=\"Asp.NET Core + MongoDB + Event Store \u0130le Event Sourcing Read Data Store Uygulamas\u0131(\u00d6rneklendirme)\" width=\"429\" height=\"793\" class=\"size-full wp-image-22089\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-7.png 429w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/Asp.NET-Core-MongoDB-Event-Store-Ile-Event-Sourcing-Read-Data-Store-UygulamasiOrneklendirme-7-162x300.png 162w\" sizes=\"auto, (max-width: 429px) 100vw, 429px\" \/><\/a><p id=\"caption-attachment-22089\" class=\"wp-caption-text\">Mevcut bir datan\u0131n var oldu\u011fu s\u00fcrece ya\u015fad\u0131\u011f\u0131 t\u00fcm etkinlikleri g\u00f6zlemleyebilmenin getirdi\u011fi avantaj\u0131 tadabilmek i\u00e7in bir \u00f6rnek&#8230;<\/p><\/div>\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 indirebilmek i\u00e7in <a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2021\/06\/EventSourcing_Example_With_EventStore.zip\" rel=\"noopener\" target=\"_blank\">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, \u00d6nceki Asp.NET Core + Event Store \u0130le Event Sourcing Uygulamas\u0131(\u00d6rneklendirme) ba\u015fl\u0131kl\u0131 yaz\u0131mda bir veri \u00fczerinde yap\u0131lan t\u00fcm i\u015flemleri Event Store tool&#8217;u ile kay\u0131t alt\u0131na alm\u0131\u015f ve b\u00f6ylece Event Sourcing&#8217;in Write Data Store kanad\u0131n\u0131&#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":21677,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,153,3573],"tags":[4217,4313,4314,4315,4225,2534,2533,4316,4317],"class_list":["post-22040","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-design-pattern","category-microservices","tag-event-sourcing","tag-event-sourcing-mongodb","tag-event-sourcing-read-data-store","tag-event-sourcing-write-data-store","tag-event-store","tag-mongodb","tag-nosql","tag-read-data-store","tag-write-data-store"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/22040","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=22040"}],"version-history":[{"count":44,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/22040\/revisions"}],"predecessor-version":[{"id":22093,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/22040\/revisions\/22093"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/21677"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=22040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=22040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=22040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}