Dependency injection (bağımlılık enjeksiyonu), SOLID prensiplerinden sonuncu olan Dependency Inversion prensibini uygulayan bir design pattern’dir. Bu pattern, bir bileşenin diğer bileşenlere olan bağımlılıklarını doğrudan tanımlamak yerine, dışarıdan gelen bir arayüzle bu bağımlılıkları enjekte etmek yoluyla sağlar.
Bu pattern, bir uygulamanın kodunun daha esnek, bakımı daha kolay ve test edilebilir olmasını sağlar. Bağımlılık enjeksiyonu sayesinde, bir bileşenin içinde kullanılan diğer bileşenlerin kodu değiştirilmeden, bileşenin davranışı ve işlevselliği değiştirilebilir veya farklı bir bileşenle değiştirilebilir.
Bağımlılık enjeksiyonu, birçok programlama dilinde ve framework’te kullanılabilir ve özellikle büyük ve karmaşık uygulamalar için önemlidir. Bu teknik, yazılımın kalitesini artırırken, uygulamanın tasarımını daha sade ve anlaşılır hale getirir.
Asp.Net Core’da Dependency Injection built-in olarak gelmektedir. Bununla ilgili basit bir örnek yaparak nasıl kullanıldığını göstermek istiyorum.
Örnek Proje:
Aşağıdaki gibi Asp.Net Core’da Web Api olarak yazılmış bir projemiz olsun ve projemiz bize Student nesnesi üstünde işlemler yapıp sonuç döndürsün. Proje içerisinde Repository ve Service katmanları için kullandığımız interface’leri container’a register edelim ve kullanalım. İlk olarak domain objemizi aşağıdaki gibi yaratalım.
1 2 3 4 5 6 7 8 | namespace DependencyInjection.Domain { public class Student { public Guid Id { get; set; } public string Name { get; set; } } } |
Sonrasında yukarıda oluşturduğumuz Student için IStudentRepository interface ve StudyRepository Class’ını oluşturalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | namespace DependencyInjection.Repository { public interface IStudentRepository { IEnumerable GetAll(); } public class StudentRepository : IStudentRepository { public IEnumerable GetAll() { return new List { new Student { Id = Guid.NewGuid(), Name = "Student-1" }, new Student { Id = Guid.NewGuid(), Name = "Student-2" } }; } } } |
Yukarıda oluşturduğumuz IStudentRepository.cs interface’i aşağıda tanımlayacağımız StudentService.cs sınıfına constructor-injected parametre olarak vereceğiz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | namespace DependencyInjection.Services { public interface IStudentService { IEnumerable GetAllStudents(); } public class StudentService:IStudentService { private readonly IStudentRepository _studentRepository; public StudentService(IStudentRepository studentRepository) { this._studentRepository = studentRepository; } public IEnumerable GetAllStudents() { return this._studentRepository.GetAll(); } } } |
Yukarıda kullandığımız StudentRepository ve StudentService nesnelerini
Container’a implementasyonlarını belirterek register etmemiz gerekiyor.
Bunun için Startup.cs’de proje ilk run edildiğinde ilgili kullanılan
bağımlılıkları register edeceğiz. Startup.cs de bulunan
ConfigureServices adlı metot register işlemlerini yapmak için default
gelen bir metottur. Aşağıdaki gibi tanımlamalarımızı yapiyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | namespace DependencyInjection { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddScoped<IStudentRepository,StudentRepository>(); services.AddScoped<IStudentService,StudentService>(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseHttpsRedirection(); app.UseMvc(); } } } |
Container Register
Asp.Net Core’da default gelen DI container’a, class ve servisleri default gelen 3 farklı extension metod ile yapabiliriz.
Bunlar:
- AddScoped()
- AddTransient()
- AddSingleton()
AddScoped(): metodu ile register edilen nesneler her request scop’unda sadece bir instance oluşturulur.
AddTransient(): metodu ile register edilen nesneler her çağrıldığında yeni bir instance oluşturulur.
AddSingleton(): metodu ile register edilen nesneler uygulama başlarken sadece bir tane instance oluşur.
Yukarıda görüldüğü üzere IStudentRepository ve IStudentService arayüzlerinin implementasyonlarını belirterek AddScoped() metodunu kullanarak register ettik. Buradaki AddScoped metodu bize Api ye gelen her bir istek için oluşturulacak nesneden sadece bir tane instance oluşturulacağının garantisini veriyor.
Controller Tarafında Kullanma
Aşağıdaki gibi StudentController içerisinde Container’da register edilen instance’ları kullanarak geriye StudentList geri dönderiyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | namespace DependencyInjection.Controllers { [Route("api/[controller]")] [ApiController] public class StudentController : ControllerBase { private readonly IStudentService _studentService; public StudentController(IStudentService cityService) { this._studentService = cityService; } [HttpGet] public IEnumerable GetStudentList() { return this._studentService.GetAllStudents(); } } } |
Asp.Net Core için Dependency Injection kullanım örneği bu kadardır.
Burada constructor-injected olarak gerekli nesneleri üretmiş olduk.
Yukarıdaki end-point’e istek atarak geriye “Student-1” ve “Student-2”
öğrencilerinin bulunduğu diziyi dönüyor.
1 2 3 4 5 6 7 8 9 10 | [ { "id": "8bf4a343-347c-4557-aa70-52691629f1a7", "name": "Student-1" }, { "id": "e760844b-53a2-44c5-87a9-14dcbb59d0a4", "name": "Student-2" } ] |
Umarım faydalı olmuştur.
Hiç yorum yok:
Yorum Gönder