Dependency Injection ve .NET Core

Dependency Injection ve .NET Core

Bu makale, NET Core'da Dependency Injection kullanımına odaklanıyor Dependency Injection, bir sınıfın başka bir sınıfa olan bağımlılığı çözmek için kullanılır ve NET Core'da Constructor Injection, Scoped Lifetime, Transient Lifetime ve Singleton Lifetime gibi özelliklerle kullanılabilir Bu yöntem sayesinde kod daha modüler hale gelir, test edilebilirlik artar ve bağımlılıkların yönetimi daha kolay hale gelir Yaşam döngülerinin belirlenmesi, Scoped Lifetime ve Transient Lifetime seçeneklerinden oluşurken, Singleton Lifetime ise uygulama boyunca tek bir örnek oluşturulmasını sağlar

Dependency Injection ve .NET Core

Bu makale, .NET Core'nun güçlü araçlarından biri olan Dependency Injection konusunu ele alıyor. Dependency Injection, bir sınıfın başka bir sınıfa olan bağımlılığını çözmek için kullanılan bir yöntemdir. Bu yöntem sayesinde, bağımlılıklar sınıfın dışında belirlenir ve burada sınıfın kendisi için kullanılır.

Dependency Injection, .NET Core'da kullanılmak üzere, farklı bağımlılıkların enjekte edilmesini mümkün kılan birçok araç sunar. Bu araçlar, Constructor Injection, Scoped ve Transient Lifetime ve Singleton Lifetime gibi özellikleri içerir. IServiceCollection ve IServiceProvider gibi çeşitli araçlar sayesinde, Dependency Injection kullanımı kolaylaşır ve daha etkili hale gelir.

Bu makale, Dependency Injection'un .NET Core'da kullanılması konusunda ayrıntılı bilgiler sunmaktadır. Dependency Injection'un avantajlarından biri, kodun daha modüler hale gelmesini sağlayarak farklı sınıfların bir araya gelmesini kolaylaştırmasıdır. Ayrıca Dependency Injection, test edilebilir kod yazmayı sağlar ve kodun daha okunaklı ve daha az bağımlılık içerdiğini garanti eder.


Dependency Injection Nedir?

Dependency Injection, bir sınıfın başka bir sınıfa olan bağımlılığının enjekte edilmesi anlamına gelir. Bu, sınıfın bir başka sınıfa doğrudan bağımlı olmaktan çıkarılması ve bağımlılıklarının daha yönetilebilir hale getirilmesi için kullanılır. Dependency Injection, sınıfın enjekte edildiği yerde kaynak bağımlılıklarının gerçekleşmesini sağlar. Bu, sınıflar arasındaki sıkı bağlantıları ortadan kaldırır ve kodun yeniden kullanılabilirliğini ve bakımını kolaylaştırır.

Dependency Injection'ın bir diğer önemli faydası, test edilebilir kod yazmanın kolaylaştırılmasıdır. Bağımlılıkların enjekte edilmesi, sınıfın kendinden bağımsız olarak test edilmesine olanak tanır. Buna ek olarak, Dependency Injection kodun daha okunaklı ve daha az bağımlılık içerdiğini sağlamaktadır.

Bir sınıfın enjekte edilmesi için birden çok yöntem vardır. Constructor Injection, bağımlılıkların sınıfın yapıcı metodunda belirlenmesini sağlar. Scoped Lifetime, her isteğe özel bir örnek oluştururken, Transient Lifetime her istekte yeni bir örnek oluşturur. Singleton Lifetime ise uygulamanın boyunca tek bir örnek oluşturulmasını sağlar. Tüm bu unsurlar, Dependency Injection'ın enjekte edildiği yerde kontrol edilebilmesini sağlayan Service Provider aracılığıyla yönetilir.


Constructor Injection

Constructor Injection, .NET Core'da Dependency Injection kullanırken sık sık karşılaşılan bir yöntemdir. Sınıfların başka sınıflara olan bağımlılıklarının oluşturulma aşamasında belirlenmesini sağlar. Yani sınıfın yapıcı metodunda bağımlılıkların yerine getirilmesi için gerekli olan kodlama yapılmaktadır.

Bu yöntem sayesinde, sınıfların enjekte edilmesi daha kolay hale gelir ve kodun okunaklığı artar. Ayrıca, bu yöntem ile bağımlılıkların soyutlanması sayesinde de test edilebilir kodların yazılması mümkün hale gelir.

Bir sınıfın birden fazla bağımlılığı varsa, bu bağımlılıkların tek tek yapıcı metoduna verilmesi yerine IServiceCollection aracılığıyla enjekte edilebilirler. Bu sayede kodun daha az bağımlılık içerdiği ve daha modüler hale geldiği gözlemlenebilir.

Bunun yanı sıra, Scoped Lifetime ve Transient Lifetime gibi yaşam döngüleri de Constructor Injection ile belirlenebilir. Scoped Lifetime'da, her isteğe özel bir örnek oluşturulurken, Transient Lifetime her istek için yeni bir örnek oluşturur. Ayrıca Singleton Lifetime da Constructor Injection ile kullanılabilir ve uygulamanın boyunca tek bir örnek oluşturulmasını sağlar.


Scoped ve Transient Lifetime

Dependency Injection yöntemi ile, yaşam döngüsü konusunda iki farklı seçeneğimiz vardır: Scoped Lifetime ve Transient Lifetime.

Scoped Lifetime, bir bağımlılığı bir kez oluşturduktan sonra, her isteğe özel bir örnek oluşturur. Bu örnek, tipik olarak bir HTTP isteğiyle başlatılır ve tamamlanır.

Buna karşılık, Transient Lifetime her istekte yeni bir örnek oluşturur. Bu, örneğin bir hizmet çağrısı yapmak gibi çeşitli işlemler sırasında kullanışlı bir yöntemdir.

Lifetime Tipi Kullanım Senaryosu
Scoped Lifetime Veritabanı işlemleri, HTTP istekleri, sıralı işlemler
Transient Lifetime Hizmet çağrıları, işlemler sırasında örneklerin yeniden kullanılmasına ihtiyaç duyulmayan işlemler

Scoped Lifetime, özellikle HTTP istekleri arasında bağımsızlık sağladığı için çok önemlidir ve bu özellik sayesinde, örnekler bir servis çağrısı sırasında paylaşılmaz. Bu, bir HTTP isteğiyle başlatılan bir işlemdeki bir değişkende yapılacak bir değişikliğin, farklı bir HTTP isteği sırasında aynı değişkeni etkilememesi anlamına gelir.

Bununla birlikte, Transient Lifetime, uygulamalarda küçük işlemler için kullanışlıdır. Örnek olarak, bir kredi kartı ödemesi yapmak gibi bir hizmet çağrısı sırasında, Transient Lifetime ile hizmet nesnesi kullanarak tek seferlik bir işlem gerçekleştirebilirsiniz.


Singleton Lifetime

Dependency Injection'da Singleton Lifetime, uygulama boyunca sadece bir örnek oluşturulmasını sağlar. Bu, özellikle bir servisin birden çok yerde kullanılması gerektiğinde veya kaynak tüketiminde tasarruf sağlamak istediğimizde kullanışlıdır. Ancak, büyük uygulamalarda tek bir örneğin tüm örneklerin ihtiyaçlarını karşılaması mümkün olmayabilir.

Singleton Lifetime, ConfigureServices metodunda AddSingleton() seçeneği kullanılarak kaydedilebilir. Bu işlem, tüm uygulamanın tek bir örnek oluşturmasını sağlar. Fakat kaynakların tek bir örnekle paylaşılması, hataların ve performans sorunlarının ortaya çıkması riskini de artırır. Bu yüzden, özellikle büyük uygulamalarda Singleton Lifetime kullanırken ihtiyatlı olunmalıdır.


Service Provider

= Dependency Injection, uygulama geliştirirken sınıfların birbirine bağımlılığından kaçınmayı hedefleyen bir yapıdır. Bu yapıda, sınıflardaki bağımlılıkların enjekte edilmesi işlemi Service Provider ile gerçekleştirilir. Service Provider, bağımlılıkları çözmek için kullanılan bir mekanizmadır. .NET Core, Service Provider desteği ile Dependency Injection yapısını destekler. Bu yapı, bağımlılıkların enjekte edilmesini kolaylaştırarak daha okunaklı, test edilebilir ve düzenli kod yazmayı sağlar. Böylece, uygulama birbiriyle bağımlı sınıfların daha yönetilebilir hale gelir.

Service Provider kullanımı, IServiceCollection ve IServiceProvider arayüzlerini kullanarak gerçekleştirilir. IServiceCollection, bağımlılıkların kaydedileceği bir koleksiyondur. IServiceProvider ise kaydedilen bağımlılıkların çözümleneceği bir mekanizmadır. IServiceCollection'ı kullanarak, uygulama geliştiricileri, hangi sınıfların bağımlılıklarının bulunduğunu ve bu bağımlılıkların nasıl çözümleneceğini tanımlayabilirler. Böylece, uygulamayı başlatma işlemi esnasında IServiceProvider enjekte edilir ve IServiceCollection üzerinden bağımlılıklar çözümlenir.

Service Provider sayesinde, uygulama geliştiricileri sınıfların bağımlılıklarını enjekte etmenin yanı sıra, hangi sınıfların ne zaman ve hangi ömür boyunca bellekte tutulacağı gibi detayları da belirleyebilirler. Bu sayede, uygulamanın daha iyi yönetilebilir hale gelmesi sağlanır. Bu nedenle, .NET Core kullanan uygulama geliştiricileri, Service Provider mekanizmasını kullanarak, bağımlılıkları yönetebilir ve uygulamayı daha modüler hale getirerek geliştirebilirler.


ASP.NET Core ve Dependency Injection

ASP.NET Core, Dependency Injection kullanımını basitleştirerek, enjekte edilmiş nesnelerin bağlamını yönetir. Dependency Injection ile kodunuz daha esnek hale gelir ve bağımlılık içermeyen daha okunaklı bir kod üretmenize izin verir. Ayrıca, Dependency Injection, tek bir yapı sağlar ve bu sayede tüm uygulamanızda birden fazla yerde kullanabilirsiniz.

ASP.NET Core'da, bağımlılıkları tanımlamak için IServiceCollection kullanılır. Bu koleksiyon, Startup.cs dosyasında ConfigureServices () metodunda kullanılır. Bu metod, ConfigureServices için yapacağınız tüm değişiklikleri yönetmenizi sağlar. Dependency Injection, tipik olarak bir sınıfın yapıcı metodunda kullanılsa da, aslında kolay bir şekilde uygulanabilir. Enjekte edilebilecek nesneleri IServiceCollection'a eklemek için AddSingleton (), AddScoped (), veya AddTransient () metodunu kullanabilirsiniz.

IServiceProvider, IServiceCollection'da tanımlanan tüm nesnelere erişmenize olanak tanır. Dependency Injection kullanıldığında, kodunuzu daha modüler ve genişletilebilir hale getirebilirsiniz. Bu kodlamayı geliştirmek için, kodunuzu daha küçük, daha okunaklı parçalara bölebilir ve bu parçaları birbirine bağlayan hizmetler ve bağımlılıklar ekleyebilirsiniz.

Dependency Injection, ASP.NET Core'da doğrudan desteklenir ve kullanımı kolay bir hal alır. Kötü bir şekilde yönetilen bağımlılıklar, uygulamanızın performansını azaltabilir ve hataların ortaya çıkmasına neden olabilir. Bu nedenle, Dependency Injection, kodun daha test edilebilir olmasını, daha okunaklı ve daha az bağımlılık içermesini sağlar.


IServiceCollection

IServiceCollection Nedir?

Dependency Injection kullanırken, bağımlılıkların nasıl tanımlandığı önemlidir. IServiceCollection, bir .NET Core uygulamasında kullanılacak tüm bağımlılıkların kaydedildiği bir koleksiyondur. Bu, uygulamanın öğelerinin nasıl oluşturulacağına ilişkin bilgiyi yönetmeye yardımcı olur.

IServiceCollection kullanarak yapılan kayıtlar, bir sınıftan istemci koduna bağımlılık eklemeden servislerin enjekte edilmesini sağlar. IServiceCollection, bir sınıfın üç farklı şekilde kaydedilmesini sağlar: AddTransient, AddScoped ve AddSingleton.

Fonksiyon Açıklama
AddTransient Her istekte yeni bir örnek oluşturarak bağımlılıkların enjekte edilmesini sağlar.
AddScoped Her istek karşılık gelen bir örnek oluşturarak bağımlılıkların enjekte edilmesini sağlar.
AddSingleton Uygulama ömrü boyunca yalnızca bir örnek oluşturarak bağımlılıkların enjekte edilmesini sağlar.

IServiceCollection, birçok farklı bağımlılığı aynı anda kaydetmek için kullanılabilir. Böylece, uygulama başlatıldığında tüm gereksinimlere kolayca erişebilirsiniz. Bağımlılıklar, ilgili sınıf ve arayüzü kullanılarak kaydedilebilir. IServiceCollection ile kaydedilebilen öğelerin bir örneklemesini, uygulama iş mantığı katmanlarında veya API çağrıları sırasında bulabilirsiniz.


IServiceProvider

AspNet Core uygulamalarındaki bağımlılıkları çözmek için .Net Core'unun temel bir bileşeni olan ServiceProvider'a ihtiyaç vardır. IServiceProvider, uygulamanın farklı yerlerinde tanımlı olan ve farklı işlevlere sahip servislerin yaratılmasını ve yönetimini sağlar. Date Provider, Logger, Config Provider vb. servisler burada tanımlanır ve yönetilir.

Bunun yanı sıra IServiceProvider ile tanımlı bir servis, örneğin bir Interface sınıfından üretilirken, sistem otomatik olarak ilgili sınıfı yükler. Bu sayede Dependency Injection bünyesinde kaydedilen tüm bağımlılıklar sorgulanabilir hale gelir. Böylece, uygulamanın sürekli bellek yüklenmesi önlenir ve bellek kullanımı optimize edilmiş olur.

AspNet Core uygulamalarında, servislerin kaydedilmesi IServiceCollection yapısında yapılırken, kaydedilen servislerin kullanılması ise IServiceProvider yapısıyla gerçekleştirilir. Bu yapılar arasında yapılacak doğru bağlantılar ile uygulamanın tamamındaki bağımlılık yönetimi sağlanabiliyor.

IServiceProvider, .NET Core ve ASP.NET Core için önemli bir yapıdır. Kullandığı DI Container sayesinde, yerelleştirerek tasarlanmıştır ve hızlıdır. Nihayetinde servis container, uygulama içindeki farklı sınıflar ve fonksiyonlar arasındaki bağımlılıkları çözer.


Dependency Injection Avantajları

Dependency Injection, yazılım geliştirme sürecinde birçok avantaj sağlamaktadır. Bu avantajlardan en önemlisi test edilebilir kod yazmayı sağlamasıdır. Dependency Injection kullanarak sınıflar birbirinden daha bağımsız hale geldiği için yazılan kodlar daha az hata verir ve test edilebilir olur. Ayrıca, Dependency Injection kodun daha okunaklı hale gelmesini sağlar. Bunun sebebi, sınıflarda kullanılan bağımlılıkların enjekte edilmesi sayesinde kodun daha az sayıda bağımlılık içermesi ve daha net bir yapıya sahip olmasıdır.

Bunun yanı sıra, modüler kod geliştirme olanağı sunar. Dependency Injection kullanarak farklı sınıfları bir araya getirerek daha büyük projelerin parçalara ayrılması kolaylaşır. Bu şekilde projeler daha okunaklı ve daha yeniden kullanılabilir hale gelir. Dependency Injection kullanarak kodun test edilebilir hale gelmesi, yazılımın daha güvenli ve sağlam olması anlamına gelir. Ayrıca yazılımın içinde yapılacak değişiklikler daha kolay uygulanabilir hale gelir.

Avantajlar Dezavantajlar
- Test edilebilir kod yazmayı sağlar - Başlangıçta daha fazla zamana ihtiyaç duyulabilir
- Kodun daha okunaklı hale gelmesini sağlar - Hatalı bir yapılandırma, çalışma zamanı hatalarına sebep olabilir
- Kodun az sayıda bağımlılık içermesi
- Modüler kod geliştirme olanağı sunar

Modüler Kod Geliştirme

Dependency Injection, kod geliştirme açısından önemli avantajlar sağlar. Bunlardan biri, kodun daha modüler hale getirilmesi ve farklı sınıfların bir araya gelmesiyle oluşturulmasıdır. Modüler kod geliştirme, büyük projelerde oldukça önemlidir; çünkü projenin büyüklüğü arttıkça, kodun anlaşılırlığı ve bakımı da zorlaşmaktadır. Dolayısıyla, bu durum geliştiricilerin zamanını fazlasıyla tüketir ve projenin başarısız olmasına yol açabilir.

Dependency Injection ile birlikte, farklı sınıfların bir araya gelmesi ve birbirleriyle etkileşimi daha kolay hale gelir. Bağımlılıklar daha net belirlendiği için, kodu daha modüler ve anlaşılır hale getirmek mümkündür. Ayrıca, bu sayede sınıfların birbirine bağımlılığı azaltılarak, daha az hata yapma şansı ortaya çıkar.

Bunun yanı sıra, modüler kod geliştirme sayesinde, projeye yeni özellikler eklendiğinde veya mevcut özellikler değiştirildiğinde, bunların projeye olan etkisi daha kolay bir şekilde tespit edilebilir. Yani, bir özelliğin diğer özelliklere ne kadar bağımlı olduğu daha net bir şekilde görülebilir ve buna göre kod üzerinde değişiklikler yapılabilir.

Dependency Injection kullanmak, kodun daha modüler hale gelmesi ve bakımının daha kolay bir hale gelmesini sağlar. Bu sayede, projeler daha kolay geliştirilir ve daha az hata ile tamamlanır.