Her Servisin Gizli Hazinesi: Mikroservislerle Database Per Service Hikayesi

2023-05-26 | #database-per-service #microservice

Bilgisayarlar Diyarı’nın bir başka köşesinde, Mikroservisler Şehri’nde, her mikroservisin kendi veritabanına sahip olduğu farklı bir dünya vardı. Bu model, “Her Servis için Veritabanı” olarak adlandırılmıştı. Bu dünyada, her mikroservis kendi hazine sandığına, yani kendi veritabanına sahipti. Bu sandıklar, her bir mikroservisin ihtiyaç duyduğu verileri içerirdi ve sadece ilgili mikroservis tarafından erişilebilirdi. Tıpkı bir masal kahramanının kendi hazine sandığına sahip olması gibi, her mikroservis de kendi veritabanına sahipti. Bir gün, Sipariş Mikroservisi, yeni bir sipariş oluşturma görevi aldı.

Continue reading 


Küçük Bir Eğlence Dünyası: Saga Pattern

2023-05-26 | #mikroservis #saga-pattern

Hoş geldin, maceracı arkadaşım! Bugün seni fantastik bir yolculuğa çıkaracağım. Bilgi Krallığı’nın hikayeler, bilgiler ve bulmacalarla dolu derinliklerine doğru büyülü bir seyahat, tam da senin gibi bir kod yazarı kahramanı için! Adımlarımızı Saga Pattern’ın büyülü dünyasına doğru yönlendireceğiz. Peki, bavulunu hazırladın mı? O zaman yola koyulalım! Saga Pattern’ın Destansı Kökenleri Bir hikayeye başlamadan önce, tıpkı saga yazarlarının yaptığı gibi, konunun kökenlerine bir göz atalım. Saga, İskandinavya’da, özellikle İzlanda’da ortaya çıkan, genellikle tarihi olayları ve kahramanları anlatan bir hikaye türüdür.

Continue reading 


Teknoloji ve Felsefe Diyalogları

2023-05-25

Uzun zamandır düşündüğüm ama bir türlü hayata geçiremediğim ilginç (en azından benim için) bir seriye başlamak istiyorum. Bildiğim, özümsediğim kadarı ile tarihi filozoflar ile teknolojik konularda onların kendi ideolojileri bağlamında diyaloglara girmek. Bunun içinde ilk kavram olarak mikroservis konusunu seçtim. Bakalım filozoflarımız bu konu hakkında neler konuşacak.

Continue reading 


Basit Bir Rest Api Client Geliştirelim 9

2023-05-14 | #diy-rest-api-client #do-it-yourself #net #rest-api

HTTP isteklerini izlemek ve teşhis etmek için daha fazla yetenek ekleyerek, kütüphanemizi daha da geliştirebiliriz. Bu amaçla, isteklerin ve yanıtların bazı temel bilgilerini loga kaydeden bir middleware ekleyelim. Bu özellik, HTTP isteklerinin ve yanıtlarının kaydını tutmak için HttpClient‘in DelegatingHandler sınıfını kullanır. Bu, bir HTTP isteği gönderildiğinde ve bir yanıt alındığında çalışan bir kod parçasıdır. Bu durumda, HTTP isteklerinin ve yanıtlarının bazı temel bilgilerini loga kaydeder. Aşağıda, bu özelliği eklemek için gereken kod parçacığı bulunmaktadır:

Continue reading 


Basit Bir Rest Api Client Geliştirelim 8

2023-05-12 | #diy-rest-api-client #do-it-yourself #net #rest-api

Bu noktada, geliştirmemiz gereken bir diğer önemli konu da güvenlikle ilgili olabilir. Özellikle, API çağrıları genellikle belirli bir kimlik doğrulama yöntemi gerektirir. Bunu sağlamak için, HTTP istemcimizi çok kullanılan iki kimlik doğrulama yöntemiyle, yani Basic Authentication ve Bearer (Token) Authentication ile uyumlu hale getirebiliriz. Bu amaçla, istemcimize iki yeni metot ekleyelim: public void SetBasicAuthentication(string username, string password) { var basicAuthValue = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")); SetDefaultHeader("Authorization", $"Basic {basicAuthValue}"); } public void SetBearerToken(string token) { SetDefaultHeader("Authorization", $"Bearer {token}"); } Bu metodlar, Authorization başlığını ayarlar, böylece her HTTP talebi kimlik doğrulama bilgilerini içerir.

Continue reading 


Basit Bir Rest Api Client Geliştirelim 7

2023-05-12 | #diy-rest-api-client #do-it-yourself #net #rest-api

Birkaç özelleştirilebilir başlık ayarlama yeteneği ekleyelim. Bu özellik, belirli bir istek için özel HTTP başlıkları ayarlamayı kolaylaştıracaktır. using Newtonsoft.Json; using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; public class MyHttpClient : IDisposable { private readonly HttpClient _client; private readonly IPolicyRegistry<string> _policyRegistry; private readonly ILogger<MyHttpClient> _logger; public MyHttpClient(HttpClient client, IPolicyRegistry<string> policyRegistry, ILogger<MyHttpClient> logger, string baseAddress, TimeSpan? timeout = null, HttpMessageHandler handler = null) { _client = handler == null ?

Continue reading 


Basit Bir Rest Api Client Geliştirelim 6

2023-05-12 | #diy-rest-api-client #do-it-yourself #net #rest-api

HTTP yanıtının durum kodlarını kontrol edebilme yeteneğini ekleyelim. Bu özellik, HTTP isteğinin başarılı olup olmadığını veya belirli bir hata durumunu gösterip göstermediğini belirlememize olanak sağlar. using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; public class MyHttpClient : IDisposable { private readonly HttpClient _client; private readonly IPolicyRegistry<string> _policyRegistry; private readonly ILogger<MyHttpClient> _logger; public MyHttpClient(HttpClient client, IPolicyRegistry<string> policyRegistry, ILogger<MyHttpClient> logger, string baseAddress, TimeSpan?

Continue reading 


Basit Bir Rest Api Client Geliştirelim 5

2023-05-12 | #diy-rest-api-client #do-it-yourself #net #rest-api

Daha fazla işlevsellik eklemek için, hata günlüğü ve otomatik hata izleme ekleyebiliriz. Bu, hataların daha kolay izlenmesine ve işlenmesine olanak sağlar. Bunun için, ILogger arabirimi kullanılarak hataların kaydedilmesini sağlayabiliriz. using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; public class MyHttpClient : IDisposable { private readonly HttpClient _client; private readonly IPolicyRegistry<string> _policyRegistry; private readonly ILogger<MyHttpClient> _logger; public MyHttpClient(HttpClient client, IPolicyRegistry<string> policyRegistry, ILogger<MyHttpClient> logger, string baseAddress, TimeSpan?

Continue reading 


Basit Bir Rest Api Client Geliştirelim 4

2023-05-12 | #diy-rest-api-client #do-it-yourself #net #rest-api

Bir sonraki adımda, HTTP istemci sınıfımızda önbellekleme ve otomatik yeniden deneme gibi özellikler ekleyebiliriz. Bu özellikler, API isteklerini daha verimli ve dayanıklı hale getirir. Bu geliştirmeleri yapmak için, Polly adlı bir kütüphaneyi kullanacağız. using Polly; using Polly.Caching; using Polly.Caching.Memory; using Polly.Registry; using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; public class MyHttpClient : IDisposable { private readonly HttpClient _client; private readonly IPolicyRegistry<string> _policyRegistry; public MyHttpClient(HttpClient client, IPolicyRegistry<string> policyRegistry, string baseAddress, TimeSpan?

Continue reading 


Basit Bir Rest Api Client Geliştirelim 3

2023-05-12 | #diy-rest-api-client #do-it-yourself #net #rest-api

Geliştirme vakti BaseAddress özelliği, zaman aşımı süresini ayarlamak ve özelleştirilebilir bir HttpMessageHandler ekleyelim. Ayrıca, bu sınıf artık bir Authorization header ı alabilsin. using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; public class MyHttpClient : IDisposable { private readonly HttpClient _client; public MyHttpClient(HttpClient client, string baseAddress, TimeSpan? timeout = null, HttpMessageHandler handler = null) { _client = handler == null ? client : new HttpClient(handler); _client.BaseAddress = new Uri(baseAddress); if (timeout.

Continue reading 


Basit Bir Rest Api Client Geliştirelim 2

2023-05-12 | #diy-rest-api-client #do-it-yourself #net #rest-api

Bu versiyonda, bir dizi başlık bilgisi, özelleştirilmiş zaman aşımı süresi ve daha fazla hata kontrolü ekleyelim: using System; using System.Collections.Generic; using System.Net.Http; using System.Text; using System.Threading.Tasks; public class MyHttpClient : IDisposable { private readonly HttpClient _client; public MyHttpClient(TimeSpan? timeout = null) { _client = new HttpClient(); if (timeout.HasValue) { _client.Timeout = timeout.Value; } } private HttpRequestMessage CreateRequest(string uri, HttpMethod method, string jsonData = null, Dictionary<string, string> headers = null) { var request = new HttpRequestMessage(method, uri); if (headers !

Continue reading 


Basit Bir Mock Framework Geliştirelim 6

2023-05-11 | #diy-mocking-framework #do-it-yourself #mock #net #reflection

Şimdiye kadar, mock nesnesinin belirli bir metodu çağırıldığında belirli bir sonuç döndürmesini, bir dizi sonuç döndürmesini veya bir hata fırlatmasını ayarlayabiliyoruz. Ancak, bazen bir metodu çağırıldığında belirli bir eylemi gerçekleştirmesini isteyebiliriz. Bu, genellikle “Callback” olarak adlandırılır. Bu özellik, bir metot çağrıldığında gerçekleşecek bir eylemi ayarlamak için kullanılabilir. Bu eylem, bir metot çağrıldığında herhangi bir işlemi gerçekleştirebilir. Örneğin, bir metot çağrıldığında belirli bir değişkenin değerini artırabiliriz, ya da belirli bir başka metodu çağırabiliriz.

Continue reading 


Basit Bir Mock Framework Geliştirelim 5

2023-05-11 | #diy-mocking-framework #do-it-yourself #mock #net #reflection

Şu anda, bizim Mock sınıfımızda bir metodun belirli bir sonucu döndürmesini veya bir dizi sonuç döndürmesini ayarlayabiliyoruz. Ancak, belirli bir durumda bir metot çağrıldığında bir hata fırlatmasını isteyebiliriz. Bu, genellikle “Throws” olarak adlandırılır. using System; using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; using System.Collections.Generic; public class Mock<T> : DispatchProxy { private ConcurrentDictionary<string, object> _methodResponses = new(); private ConcurrentDictionary<string, Queue<object>> _methodSequences = new(); private ConcurrentDictionary<string, Exception> _methodExceptions = new(); private ConcurrentDictionary<string, int> _methodCalls = new(); protected override object Invoke(MethodInfo targetMethod, object[] args) { var key = GetKey(targetMethod, args); var wildcardKey = $"{targetMethod.

Continue reading 


Basit Bir Mock Framework Geliştirelim 4

2023-05-11 | #diy-mocking-framework #do-it-yourself #mock #net #reflection

Mocklama kütüphanemizi daha da geliştirelim. Şu anda, bir metodun belirli parametrelerle çağrılmasını ve belirli bir sonuç döndürmesini bekliyoruz. Ancak, bazen belirli bir parametre türüne sahip bir metodu çağrıldığında belirli bir sonuç döndürmesini isteyebiliriz, parametrenin kendisinin ne olduğu önemli olmayabilir. Bu özellik, genellikle mocklama kütüphanelerinde “It.IsAny” olarak adlandırılır. Ayrıca, bir mock nesnesinin bir metodu birden fazla kez çağrıldığında farklı sonuçlar döndürmesini isteyebiliriz. Bu, genellikle “SetupSequence” olarak adlandırılır. Bu iki özelliği ekleyelim.

Continue reading 


Basit Bir Mock Framework Geliştirelim 3

2023-05-11 | #diy-mocking-framework #do-it-yourself #mock #net #reflection

Bu sefer belirli parametrelerle çağrılan metotları simüle edeceğiz ve geri dönüş değerini ayarlayabileceğiz. Ayrıca, belirli bir metot çağrısını doğrulayabileceğiz. using System; using System.Collections.Concurrent; using System.Linq.Expressions; using System.Reflection; public class Mock<T> : DispatchProxy { private ConcurrentDictionary<string, object> _methodResponses = new(); private ConcurrentDictionary<string, int> _methodCalls = new(); protected override object Invoke(MethodInfo targetMethod, object[] args) { var key = GetKey(targetMethod, args); if (_methodResponses.TryGetValue(key, out var value)) { if (_methodCalls.ContainsKey(key)) { _methodCalls[key]++; } else { _methodCalls.

Continue reading 


Basit Bir Mock Framework Geliştirelim 2

2023-05-11 | #diy-mocking-framework #do-it-yourself #mock #net #reflection

Artık interface lerle çalışalım. Öncelikle, System.Reflection.DispatchProxy‘yi kullanacağız. Bu, bir proxy sınıfı oluşturmanıza ve ona method çağrılarını yönlendirmenize olanak sağlar. DispatchProxy‘yi kullanarak belirli bir arayüzün metotlarını mocklayalım. using System; using System.Collections.Generic; using System.Reflection; public class Mock<T> : DispatchProxy { private readonly Dictionary<string, object> _methodResponses = new(); protected override object Invoke(MethodInfo targetMethod, object[] args) { if (_methodResponses.TryGetValue(targetMethod.Name, out var value)) { return value; } throw new Exception($"No response set up for method {targetMethod.

Continue reading 


Basit Bir Mock Framework Geliştirelim 1

2023-05-11 | #diy-mocking-framework #do-it-yourself #mock #net #reflection

Mocklama, testlerinizde belirli sınıfların veya metodların davranışlarını taklit etmek için kullanılır. Örneğin, bir veritabanı çağrısı yapmak yerine, bir mock veritabanı çağrısını simüle edebilirsiniz. Bu, testlerin daha hızlı çalışmasını sağlar ve testlerin bağımlılıklarını azaltır. .NET’de birçok popüler mock kütüphanesi varken neden böyle bir şey yapalım ki. Sadece nasıl çalıştığını anlamak ve biraz pratik yapmak. Ve başlayalım using System; using System.Collections.Generic; public interface IMock<T> { void When(Func<T, bool> predicate); void ThenReturn(object response); } public class Mock<T> : IMock<T> { private Dictionary<Func<T, bool>, object> responses = new(); public void When(Func<T, bool> predicate) { if (!

Continue reading 


Basit Bir Test Framework Gelistirelim 15

2023-05-11 | #diy-unittest-framework #do-it-yourself #net #reflection #unit-test

Testlerin belirli bir süre sınırlamasına tabi olması önemlidir. Bazı testlerin beklenenden daha uzun sürmesi veya sonsuz bir döngüye girmesi durumunda, süre sınırlaması olan bir test, bu tür sorunları belirlemeyi ve test sürecini düzgün bir şekilde yönetmeyi kolaylaştırır. Her test için bir süre sınırlaması ayarlamak için TestRunner‘ı güncelleyelim: using System; using System.Reflection; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Diagnostics; // ... public static class TestRunner { // ... private static async Task<(bool, string)> RunTestMethodAsync<T>(T testClassInstance, MethodInfo testMethod, object[] parameters = null) { try { var stopwatch = Stopwatch.

Continue reading 


Basit Bir Test Framework Gelistirelim 14

2023-05-11 | #diy-unittest-framework #do-it-yourself #net #reflection #unit-test

Test raporlama, testlerin sonuçlarını görselleştirmek ve anlamak için önemlidir. Testlerin sonuçlarını almak ve bunları daha anlamlı bir formatta raporlamak için bir özellik ekleyebiliriz. Basit bir test raporlama özelliği, testlerin adlarını, testlerin ne kadar sürede tamamlandığını ve hangi testlerin başarılı olduğunu veya başarısız olduğunu içerebilir. TestRunner‘ı geliştirelim: using System; using System.Reflection; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Diagnostics; // ... public static class TestRunner { // ... private static async Task<(bool, string)> RunTestMethodAsync<T>(T testClassInstance, MethodInfo testMethod, object[] parameters = null) { try { var stopwatch = Stopwatch.

Continue reading 


Basit Bir Test Framework Gelistirelim 13

2023-05-11 | #diy-unittest-framework #do-it-yourself #net #reflection #unit-test

Testlerin birbirinden izole olması önemlidir, çünkü bir testin durumu başka bir testi etkilememelidir. Bunun için, her bir test metodu çalıştırıldığında, test sınıfının yeni bir örneğini oluşturabiliriz. Bu, her bir testin kendi durumunu korumasını sağlar ve testler arasında durum paylaşımını önler. Aşağıda, bu özelliği eklemek için TestRunner‘ı güncelleyelim: using System; using System.Reflection; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; // ... public static class TestRunner { // ... public static async Task RunTestsAsync<T>(string suiteName = null) { var testMethods = typeof(T) .

Continue reading 