Blog SAkan

Blog SAkan'a Hoşgeldiniz

Aramak istediğiniz makaleyi bir kaç kelime ile giriniz
image

.NET Core ile Async Programlama

05.06.2024 tarihinde yayınlandı 1 dakikalık okuma 0 yorum
Async programlama, modern yazılım geliştirme süreçlerinde önemli bir yer tutar. .NET Core, bu konuda güçlü ve esnek araçlar sunarak geliştiricilerin performanslı ve ölçeklenebilir uygulamalar oluşturmasını sağlar. Bu makalede, .NET Core ile async programlama konusunu detaylı bir şekilde inceleyeceğiz. Async Programlamanın Temel Kavramları Async programlama, uygulamaların aynı anda birden fazla işi yapabilmesini sağlayarak performansı artırır. Bu yaklaşım, özellikle I/O işlemleri gibi uzun sürebilen operasyonlarda uygulamanın yanıt verebilirliğini korur. .NET Core'da async programlama, async ve await anahtar kelimeleri kullanılarak gerçekleştirilir. async Anahtar Kelimesi: Bir metodun asenkron olarak çalışacağını belirtir. Bu metodun içinde await kullanabilirsiniz. await Anahtar Kelimesi: Uzun sürebilecek bir işlemi beklemek için kullanılır. Bu, iş tamamlanana kadar başka işlerin yapılabilmesini sağlar. Basit Bir Örnek Aşağıda, .NET Core'da async programlamanın nasıl yapıldığını gösteren basit bir örnek bulunmaktadır. using System; using System.Net.Http; using System.Threading.Tasks; public class Program {    public static async Task Main(string[] args)    {        await FetchDataFromApi();    }    public static async Task FetchDataFromApi()    {        using (HttpClient client = new HttpClient())        {            string url = "https://api.example.com/data";            string result = await client.GetStringAsync(url); Console.WriteLine(result);        }    } } Bu örnekte, FetchDataFromApi metodu bir API'den veri çekmek için HttpClient kullanır. await anahtar kelimesi, GetStringAsync metodunun tamamlanmasını beklerken başka işlerin yapılabilmesini sağlar. Async/Await Deseninin Avantajları Yanıt Verebilirlik: Async metodlar, kullanıcı arayüzü kilitlenmeden uzun süren işlemleri gerçekleştirebilir. Kaynak Verimliliği: İşlem tamamlanana kadar bekleyen async metodlar, işlemcinin diğer işlerle meşgul olmasına olanak tanır. Kolay Okunabilirlik: Async programlama, geleneksel callback yöntemlerine göre daha okunabilir ve bakım yapılabilir kod yazmayı sağlar. .NET Core ve Async I/O Operasyonları .NET Core, çeşitli I/O operasyonlarını asenkron olarak gerçekleştirmek için geniş bir API yelpazesi sunar. Örneğin: Dosya I/O: FileStream ve StreamReader gibi sınıflar, asenkron metodlar içerir. Veritabanı Erişimi: Entity Framework Core, asenkron metodlar sunar (örneğin, SaveChangesAsync ve ToListAsync). Ağ İletişimi: HttpClient, HTTP isteklerini asenkron olarak gerçekleştirebilir. Aşağıda, bir dosyadan veri okuma işleminin asenkron olarak nasıl yapılacağını gösteren bir örnek yer almaktadır: using System; using System.IO; using System.Threading.Tasks; public class Program {    public static async Task Main(string[] args)    {        string data = await ReadFromFileAsync("example.txt"); Console.WriteLine(data);    }    public static async Task<string> ReadFromFileAsync(string filePath)    {        using (StreamReader reader = new StreamReader(filePath))        {            return await reader.ReadToEndAsync();        }    } } Dikkat Edilmesi Gerekenler Ölçeklenebilirlik: Async metodlar, özellikle web uygulamalarında ölçeklenebilirliği artırır. Ancak, her durumda async kullanmak uygun olmayabilir. CPU-bound işlemler için async programlama yerine paralel programlama teknikleri kullanılabilir. Hata Yönetimi: Async metodlar içinde hata yönetimi önemlidir. try-catch blokları kullanılarak beklenmedik hataların ele alınması gerekir. Deadlock: Yanlış kullanım durumlarında deadlock (ölümcül kilitlenme) sorunları yaşanabilir. ConfigureAwait(false) kullanarak bu tür sorunlar önlenebilir. Sonuç .NET Core ile async programlama, performanslı ve ölçeklenebilir uygulamalar geliştirmek için güçlü bir araçtır. async ve await anahtar kelimeleri ile kolayca asenkron metodlar yazabilir, uygulamanızın yanıt verebilirliğini artırabilirsiniz. Bu makalede, async programlamanın temel kavramlarını ve bazı pratik örnekleri ele aldık. Async programlama, doğru kullanıldığında uygulamalarınızı daha verimli hale getirebilir ve kullanıcı deneyimini iyileştirebilir.
Daha fazla göster
image

Decorator Design Pattern

23.05.2024 tarihinde yayınlandı 1 dakikalık okuma 0 yorum
Decorator design pattern, yazılım geliştirmede sıkça kullanılan ve sınıflara dinamik olarak yeni işlevler eklemek için kullanılan bir yapıdır. Bu makalede, .NET Core kullanarak decorator pattern'in nasıl uygulanabileceğini adım adım inceleyeceğiz. Öncelikle, decorator pattern'in ne olduğunu ve neden kullanıldığını anlayalım. Decorator Design Pattern Nedir? Decorator pattern, bir nesnenin davranışını, orijinal nesnenin kodunu değiştirmeden genişletmenize olanak tanır. Bu, nesneye ek sorumluluklar yükleyerek daha esnek ve ölçeklenebilir bir tasarım sağlar. Decorator pattern, inheritance yerine composition kullanarak yeni işlevler eklemeyi tercih eder. Ne Zaman Kullanılır? Decorator pattern şu durumlarda kullanışlıdır: Bir nesneye dinamik olarak sorumluluklar eklemek istiyorsanız. Sınıfların birden fazla kombinasyonunu oluşturmak için sınıf hiyerarşisi yerine daha esnek bir çözüm arıyorsanız. Sınıfın temel işlevselliğini değiştirmeden yeni özellikler eklemek istiyorsanız. Örnek Senaryo Bir kahve dükkanı uygulaması geliştirdiğinizi varsayalım. Farklı kahve türleri (Espresso, Latte, Mocha, vb.) ve bu kahvelere eklenebilecek farklı ekstralar (Süt, Çikolata, Vanilya, vb.) bulunmaktadır. Bu kombinasyonları ele almak için decorator pattern kullanabiliriz. Uygulama Adımları 1. Adım: Temel Arayüz ve Sınıfı Oluşturma Öncelikle, kahvemiz için bir ICoffee arayüzü tanımlayalım ve bu arayüzü uygulayan bir Espresso sınıfı oluşturalım. public interface ICoffee {    string GetDescription();    double GetCost(); } public class Espresso : ICoffee {    public string GetDescription()    {        return "Espresso";    }    public double GetCost()    {        return 2.0; // Espresso fiyatı    } } 2. Adım: Decorator Sınıfı Oluşturma Bir CoffeeDecorator sınıfı oluşturup, bu sınıfı ICoffee arayüzünden türetelim. Diğer dekoratör sınıflarımız bu sınıftan miras alacak. public abstract class CoffeeDecorator : ICoffee {    protected ICoffee _coffee;    public CoffeeDecorator(ICoffee coffee)    {        _coffee = coffee;    }    public virtual string GetDescription()    {        return _coffee.GetDescription();    }    public virtual double GetCost()    {        return _coffee.GetCost();    } } 3. Adım: Dekoratör Sınıfları Oluşturma Şimdi, ekstralarımız için dekoratör sınıflarını oluşturalım. Örneğin, MilkDecorator ve ChocolateDecorator sınıflarını oluşturabiliriz. public class MilkDecorator : CoffeeDecorator {    public MilkDecorator(ICoffee coffee) : base(coffee) { }    public override string GetDescription()    {        return _coffee.GetDescription() + ", Milk";    }    public override double GetCost()    {        return _coffee.GetCost() + 0.5; // Süt ek maliyeti    } } public class ChocolateDecorator : CoffeeDecorator {    public ChocolateDecorator(ICoffee coffee) : base(coffee) { }    public override string GetDescription()    {        return _coffee.GetDescription() + ", Chocolate";    }    public override double GetCost()    {        return _coffee.GetCost() + 0.7; // Çikolata ek maliyeti    } } 4. Adım: Kullanım Decorator pattern'i kullanarak kahve nesnelerini oluşturup, dinamik olarak ekstralar ekleyelim. class Program {    static void Main(string[] args)    {        ICoffee coffee = new Espresso(); Console.WriteLine($"{coffee.GetDescription()} : {coffee.GetCost()}");        coffee = new MilkDecorator(coffee); Console.WriteLine($"{coffee.GetDescription()} : {coffee.GetCost()}");        coffee = new ChocolateDecorator(coffee); Console.WriteLine($"{coffee.GetDescription()} : {coffee.GetCost()}");    } } Çıktı Espresso : 2.0 Espresso, Milk : 2.5 Espresso, Milk, Chocolate : 3.2 Sonuç Decorator design pattern, sınıflara dinamik olarak yeni işlevler eklemek için güçlü bir yol sağlar. Bu makalede, .NET Core kullanarak basit bir kahve dükkanı senaryosunda decorator pattern'in nasıl uygulanacağını gördük. Bu yaklaşım, kodunuzu daha esnek ve genişletilebilir hale getirir, sınıf hiyerarşilerini yönetmeyi kolaylaştırır. Decorator pattern'i kullanarak benzer ihtiyaçlarınıza uygun çözümler geliştirebilirsiniz. Metin için teşekkürler ai. Blog projemde ayarlar kaydedildikten sonra kod satırının devamında redis ile ayarlar cache'leniyordu. Bu design pattern sayesinde cache işlevselleğini loosely coupled şekilde projeye kazandırdık. Buraya tıklayarak projeye ulaşabilirsiniz.
Daha fazla göster
image

SignalR

25.04.2024 tarihinde yayınlandı 2 dakikalık okuma 0 yorum
İnternet üzerinde gerçek zamanlı iletişim giderek daha önemli hale gelmektedir. Web uygulamaları, kullanıcılar arasında hızlı ve etkileşimli iletişim sağlamak için teknolojik olarak gelişmektedir. Bu ihtiyaca cevap veren birçok çözüm bulunmaktadır ve SignalR, bu çözümlerden biridir. SignalR, Microsoft tarafından geliştirilen bir kütüphanedir ve gerçek zamanlı web uygulamaları oluşturmayı kolaylaştırır. İstemci ve sunucu arasında iki yönlü iletişimi destekler. Bu, sunucudaki değişikliklerin anında istemcilere iletilmesini ve istemcilerden sunucuya geri bildirim alınmasını sağlar. Özellikle sohbet uygulamaları, canlı puan tabloları, anlık bildirimler gibi gerçek zamanlı etkileşim gerektiren uygulamalarda yaygın olarak kullanılır. SignalR, WebSocket, Server-Sent Events (SSE), Long Polling gibi farklı iletişim mekanizmalarını kullanarak gerçek zamanlı iletişim sağlar. Bunların arasında en etkin olanı WebSocket'tir çünkü tam çift yönlü iletişim sağlar. Ancak, WebSocket'in desteklenmediği ortamlarda SignalR diğer yöntemlere de otomatik olarak uyum sağlar. Hub'lar (Hubs): SignalR, bir veya daha fazla hub sınıfı aracılığıyla iletişimi yönetir. Hub'lar, sunucuda gerçekleşen olayları dinler ve istemcilere bildirir. Aynı zamanda istemcilerden gelen talepleri alır ve bunları sunucu tarafında işler. Hub sınıfları, sunucu ve istemci arasındaki iletişimde aracı olarak görev yapar. İstemci ve Sunucu: SignalR, istemci ve sunucu arasında iletişimi kurar. İstemci tarafında JavaScript API'si kullanılarak sunucuyla bağlantı kurulur ve sunucudaki hub'larla etkileşim sağlanır. Sunucu tarafında ise .NET veya .NET Core ortamında hub sınıfları tanımlanır ve istemcilerle iletişim gerçekleştirilir. İletişim Protokolleri: SignalR, iletişimde WebSocket, Server-Sent Events, Long Polling gibi farklı protokolleri kullanabilir. Sunucu ve istemci arasında en etkin iletişim protokolü WebSocket'tir ancak bu protokolün desteklenmediği durumlarda diğer alternatif protokoller otomatik olarak devreye girer. Avantajları Gerçek Zamanlı İletişim: SignalR, sunucudaki değişikliklerin anında istemcilere iletilmesini sağlar, bu da gerçek zamanlı etkileşimli uygulamaların geliştirilmesini kolaylaştırır. Çoklu Platform Desteği: SignalR, .NET ve .NET Core platformlarında kullanılabilir. Ayrıca istemciler için JavaScript API'si sağlar, bu da çeşitli istemci platformlarında (web tarayıcıları, mobil uygulamalar vb.) kullanılabilmesini sağlar. Otomatik Protokol Seçimi: SignalR, desteklenen en etkin iletişim protokolünü otomatik olarak seçer. Bu sayede farklı platformlarda ve ortamlarda sorunsuz bir şekilde çalışabilir. Kolay Kullanım: SignalR, basit bir API'ye sahiptir ve gerçek zamanlı iletişim sağlamak için gerekli olan alt yapıyı sağlar. Bu da geliştiricilerin uygulama geliştirmeye odaklanmalarını kolaylaştırır. SignalR, gerçek zamanlı iletişim gerektiren web uygulamaları için güçlü bir çözümdür. Basit API yapısı ve otomatik protokol seçimi gibi özellikleriyle geliştiricilere kolaylık sağlar ve çeşitli platformlarda sorunsuz bir şekilde çalışabilir. Bu nedenle, gerçek zamanlı uygulamalar geliştiren geliştiriciler için önemli bir araçtır. İlgili kütüphaneleri ekledikten sonra basit bir örnek için aşağıdaki kodlar kullanılabilir. public interface IExampleTypeSafeHub { Task ReceiveMessageForAllClient(string message); } public class ExampleTypeSafeHub : Hub<IExampleTypeSafeHub> { public async Task BroadcastMessageToAllClient(string message) { await Clients.All.ReceiveMessageForAllClient(message); } } Program.cs'de; builder.Services.AddSignalR(); app.MapHub<ExampleTypeSafeHub>("/exampleTypeSafeHub"); Javascript tarafında; $(document).ready(function () { const connection = new signalR.HubConnectionBuilder().withUrl("/exampleTypeSafeHub").configureLogging(signalR.LogLevel.Information).build(); const broadcastMessageToAllClientHubMethodCall = "BroadcastMessageToAllClient"; const receiveMessageForAllClientClientMethodCall = "ReceiveMessageForAllClient"; async function start() { try { await connection.start().then(() => { console.log("Hub connected"); $("#div-connection-id").html(`Connection Id : ${connection.connectionId}`); }); } catch (e) { setTimeout(() => start(), 5000); } } connection.onclose(async () => { await start(); }) start(); $("#btn-send-message-all-client").click(function () { const message = "hello world"; connection.invoke(broadcastMessageToAllClientHubMethodCall, message).catch(err => console.error("error:", err)); }); connection.on(receiveMessageForAllClientClientMethodCall, (message) => { console.log("Received message:", message); }); }); Örnek projeyi github üzerinden inceleyebilirsiniz.
Daha fazla göster
image

RabbitMQ

23.04.2024 tarihinde yayınlandı 4 dakikalık okuma 0 yorum
RabbitMQ, başlangıçta Gelişmiş Mesaj Kuyruk Protokolü'nü (AMQP) uygulayan ve o zamandan beri Akış Metin Odaklı Mesajlaşma Protokolünü (STOMP) desteklemek için bir eklenti mimarisiyle genişletilen, açık kaynaklı bir mesaj aracı yazılımıdır Erlang'da yazılan RabbitMQ sunucusu, kümeleme ve yük devretme için Açık Telekom Platformu çerçevesi üzerine inşa edilmiştir. Aracıyla arayüz oluşturacak istemci kitaplıkları tüm önemli programlama dilleri için mevcuttur. Aşağıda basic şekilde kullanımı örneklendirilmiştir. public class BaseExchange { public static ConnectionFactory factory = new ConnectionFactory { HostName = "localhost", Port = 5672 }; } public enum LogNames { Critical = 1, Error = 2, Warning = 3, Info = 4 } Publisher; namespace RabbitMQ.Publisher { public class DirectExchange : BaseExchange { private const string exchangeName = "logs-direct"; public static void Publisher() { using (var connection = factory.CreateConnection()) { var channel = connection.CreateModel(); channel.ExchangeDeclare(exchangeName, durable: true, type: ExchangeType.Direct); Enum.GetNames(typeof(LogNames)).ToList().ForEach(x => { var routeKey = $"route-{x}"; var queueName = $"direct-queue-{x}"; channel.QueueDeclare(queueName, true, false, false); channel.QueueBind(queueName, exchangeName, routeKey); }); Enumerable.Range(1, 50).ToList().ForEach(x => { LogNames log = (LogNames)new Random().Next(1, 5); string message = $"Log Type: {log}"; var messageBody = Encoding.UTF8.GetBytes(message); var routeKey = $"route-{log}"; channel.BasicPublish(exchangeName, routeKey, null, messageBody); Console.WriteLine($"Message sended : {message}"); }); } } } } Subscriber (Consumer); namespace RabbitMQ.Subscriber { public class DirectExchange : BaseExchange { public static void Consumer() { using (var connection = factory.CreateConnection()) { var channel = connection.CreateModel(); channel.BasicQos(0, 1, false); var consumer = new EventingBasicConsumer(channel); var queueName = $"direct-queue-Critical"; // bu örnekte sadece critical kuyruğunu dinliyoruz channel.BasicConsume(queueName, false, consumer); Console.WriteLine($"Logs listening"); consumer.Received += (object sender, BasicDeliverEventArgs e) => { var message = Encoding.UTF8.GetString(e.Body.ToArray()); Thread.Sleep(500); Console.WriteLine($"Recieved Message : {message}"); channel.BasicAck(e.DeliveryTag, false); }; Console.ReadLine(); } } } } Örnekler için; Diğer basic yöntemleriyle kullanımı örnek proje için tıklayınız. Worker service ile excel oluşturma örneği için tıklayınız. Background service ile image watermark örneği için tıklayınız.
Daha fazla göster
image

Redis

03.04.2024 tarihinde yayınlandı 4 dakikalık okuma 0 yorum
Redis (Remote Dictionary Server), bir veri yapısı sunucusudur. Açık kaynak, bellek kullanımlı, anahtar-değer deposudur. Redis "Uzak Sözlük Sunucusu" anlamına gelmektedir. Çeşitli kaynaklara göre en çok kullanılan anahtar-değer veritabanıdır. Haziran 2015'ten beri Redis Labs şirketi tarafından geliştirilmesine destek sağlanmaktadır. Verileri geçici olarak ram’de tutma yöntemlerinden biridir. Uygulama bir servis aracılığı ile ram’e erişir. Bu da in-memory cache yöntemlerinden daha yavaş olmasına sebep olur. Ama dağıtık yapılarda veri tutarlılığı açısından tercih edilir. .Net Core tarafında aşağıdaki gibi kullanılabilir. public static class StackExchangeRedisExtension { public static void AddStackExchangeRedis(this IServiceCollection services, IConfiguration configuration) { string _redisHost = configuration["Redis:Host"]; string _redisPort = configuration["Redis:Port"]; var configString = $"{_redisHost}:{_redisPort}"; var redis = ConnectionMultiplexer.Connect(configString); services.AddSingleton(redis); } } public class StackExchangeRedisService { private readonly ConnectionMultiplexer _redis; public StackExchangeRedisService(ConnectionMultiplexer redis) { _redis = redis; } public IDatabase GetDb(int db) { return _redis.GetDatabase(db); } } Program.cs tarafına servisi ekledik. builder.Services.AddStackExchangeRedis(builder.Configuration); builder.Services.AddSingleton<StackExchangeRedisService>(); En çok Hash veri yapısı ile kullanılır; public class HashTypeController : Controller { private readonly StackExchangeRedisService _redisService; private readonly IDatabase db; private readonly string hashKey = "hashKey"; public HashTypeController(StackExchangeRedisService redisService) { _redisService = redisService; db = _redisService.GetDb(4); } public IActionResult Index() { if (!db.KeyExists(hashKey)) { db.KeyExpire(hashKey, DateTime.Now.AddMinutes(1)); } db.HashSet(hashKey, "KeyS", "Selahattin"); db.HashSet(hashKey, 2, "Ahmet"); db.HashSet(hashKey, "KeyMehmet", "Mehmet"); db.HashSet(hashKey, "KeyMehmet", "Mehmet"); return View(); } public IActionResult Show() { if (!db.KeyExists(hashKey)) return Content("hash not found"); Dictionary<string, string> list = new Dictionary<string, string>(); db.HashGetAll(hashKey).ToList().ForEach(item => { list.Add(item.Name, item.Value); }); return Content(JsonConvert.SerializeObject(list)); } public IActionResult DeleteItem() { if (!db.KeyExists(hashKey)) return Content("hash not found"); string item = "KeyS"; db.HashDelete(hashKey, item); return Content("hash deleted"); } } Burada da Set veri yapısı ile kullanımına bir örnek mevcut; public class SetTypeController : Controller { private readonly StackExchangeRedisService _redisService; private readonly IDatabase db; private readonly string ListKey = "setNames"; public SetTypeController(StackExchangeRedisService redisService) { _redisService = redisService; db = _redisService.GetDb(2); } public IActionResult Index() { if (!db.KeyExists(ListKey)) { db.KeyExpire(ListKey, DateTime.Now.AddMinutes(5)); } //SetAdd uniq itemleri tutar, aynı item birden fazla eklenemez db.SetAdd(ListKey, "Selahattin"); db.SetAdd(ListKey, "Ahmet"); bool r1 = db.SetAdd(ListKey, "Mehmet"); //true bool r2 = db.SetAdd(ListKey, "Mehmet"); //false return View(); } public IActionResult Show() { HashSet<string> names = new HashSet<string>(); if (!db.KeyExists(ListKey)) return Content("set list not found"); db.SetMembers(ListKey).ToList().ForEach(name => names.Add(name)); return Content(JsonConvert.SerializeObject(names)); } public IActionResult DeleteItem() { if (!db.KeyExists(ListKey)) return Content("set list not found"); string item = "Selahattin"; db.SetRemove(ListKey, item); return Content("set list item deleted"); } }
Daha fazla göster

Blog SAkan bir developer blogdur.

Hoşgeldiniz, mail adresinizi girerek güncel makalalelerden haberdar olabilirsiniz!