Yazılımın Bağımsızlık Sembolü: Dependency Injection

Dependencj Injection (DI) nedir konusunu N katmanlı mimari üzerinden neden kullanmalıyız şeklinde inceleyerek anlattığım bir yazıdır, keyifli okumalar dilerim.

Yazılımın Bağımsızlık Sembolü: Dependency Injection
0
Google Aramalarında 'Mühendis Ol'u Favori Kaynağınız Yapın!

Bir düşünün: Uyanıyoruz ve sabah işe gitmemiz gerekiyor. Amaç belli iş yerine ulaşmak. Peki hepimizin tek bir tip ulaşım aracıyla ulaşmak zorunda olduğunu düşünseydik nasıl olurdu? Tamamen o araca bağımlı olurduk ve tüm sistemimizi o aracın zamanına göre düzenlemek zorunda kalırdık. Fakat böyle bir bağımlılık söz konusu olmadığı için metroyla, taksiyle, otobüsle, kendi aracımızla ya da farklı bir vasıtayla ulaşımımızı sağlayabiliriz.

Peki ya günümüzdeki ödeme yöntemlerinin çeşitliliği, bizi nakit paraya olan bağımlılığımızdan kurtardı diyebilir miyiz? İnternetten sevdiğiniz şeylerle doldurulan sepeti kayıtlı bir kredi kartıyla tek tıkla ödemek, ya da QR ödemeyle kartla bile uğraşmadan telefondan hızlıca okutup market alışverişinizi gerçekleştirmek… Tüm bunlar bizim cepler dolusu nakit para taşıma zorunluluğundan kurtarıyor ve nakit paraya olan bağımlılığımızı sonlandırıyor.

Tüm bu gerçek hayattan verdiğimiz bağımlılıkların azaltılmasına yönelik örneklerimizi yazılım dünyasında da kullanıyoruz ve .NET projelerinde en çok rastladığımız kavramlardan biri olan Dependency Injection kavramıyla karşılaşıyoruz.

Peki Dependency Injection nedir?

Özetle koddaki bağımlılık yaratan nesneleri ortadan kaldırmak ve ihtiyaçları dışardan alarak bağımlılığı minimize ettiğimiz bir yapıdır. Tanım yetersiz kaldıysa olayı biraz daha detaylandıralım. .Net Core’da iki sınıf düşünelim ve bunlardan birisi diğerinin içerisinde yer alacak. Bunu da nesne örneği oluşturarak yaptığımızı varsayalım. New anahtar sözcüğünü kullanarak nesne örneği oluşturduğumuzda bellekten bir yer ayırırız ve artık bu nesneye bağımlı hale geliriz. Oysaki yazılımda istenen kodların birbirine bu şekilde sıkı bağlı olması değil, gevşek bağlı (loosely coupled) olmasıdır. Ama bu gevşek bağlılıktan kastettiğimiz alttaki gibi bir gevşeklik değil…

Def 5

N katmanlı bir mimariyle tasarladığımız ve Repository Design Pattern kullandığımız bir projemiz olduğunu varsayalım. Bu tasarım deseni ve mimariye farklı bir yazı serisinde ayrı bir pencere açacağım. Projemizde, Business katmanı içinde Concrete ve Abstract klasörlerimizi oluşturuyoruz. Concrete klasörü içinde Manager olarak isimlendirdiğimiz sınıflar ve Abstract klasörü içinde Service olarak adlandırdığımız interface’ler yer alıyor. Burda amacımız iş kuralları oluşturarak kontrolleri gerçekleştirmek.

Def 4

Alttaki kodlara göz attığımızda CategoryManager adlı class, ICategoryService isimli interface’ten inherit edilmiş ve interface’teki metot imzaları sınıfa implement edilmiş. Ne dedin şimdi burda diyorsanız terimsel konuşmak havalı olduğu için değil, yazılımda terimlere hakim olmak gerektiği için sınıf yerine class, arayüz yerine interface, kalıtım yerine inherit ve uygulamak yerine de implement etmek dedim. Peki nedir bu inherit, interface ve implement diye sorarsak, inherit için yazılım dünyasının miras hukuku diyebiliriz. Madem hukuktan girdik o zaman interface için de yazılım dünyasının sözleşme avukatı diyebiliriz. Implement etmek için ise işi yüklenen inşaat çalışanı tanımı hiç yanlış olmaz sanırım.

Def

Fakat burda terimlerden daha dikkat çekici olan şey, Data Access Layer’da yer alan EfCategoryDal sınıfı ve bu sınıftan oluşturulan _categoryDal isimli nesne örneğidir. Burdaki Ef, Entity Framework’ün kısaltmasıdır ve bir ORM(Object Relation Mapping) teknolojisidir. Kısaca ORM, veritabanı ile ilişki kurulmasını sağlayan, tabloları sınıflara, sütunları da property’lere dönüştüren bir araçtır. “Peki burdaki sorun ne, hala bahsetmedin?” Sorunumuz tam olarak da bu nesne örneğinin yaratılması. Eğer tek bir ORM teknolojisinin kullanılacağından eminsek, ilerde hiçbir şekilde farklı bir teknolojiye geçilmeyeceğinin garantisi varsa o zaman bu şekilde kullanımda sorun yok fakat farklı teknolojiler de işin içine girerse o zaman bu kullanım bizim önümüze beton gibi çıkar.

Peki o zaman ideal kullanım ne olmalı?

İdeal kullanım dediğimiz çözümü bize Dependency Injection sağlayacak, yani nesneye olan bağımlılığımızı azaltacak ve alternatiflere de geçişimizi kolaylaştıracak.

Altta nesne örneği oluşturduğumuz kod yerine eklediğimiz field ve constructor metodumuz var. Peki constructor method(yapıcı metot) ne işe yarar diye bakarsak özetle; bir sınıftan bir nesne örneği oluşturduğumuzda ilk çalışan metottur diyebiliriz, sınıf adıyla aynı olmak zorundadır ve geri dönüş değeri de yoktur.

Def 2 1

Katmanlı mimaride alttaki kodlarda görüleceği gibi Presentation katmanında Controller oluşturduğumuzda ve bu controller içerisinde ICategoryService interface’inden bir field örneklediğimizde aslında arka planda taaa Data Access katmanına kadar gitmiş oluyoruz. Çünkü her katman bir alt katmanla iletişim kuruyor. Peki nasıl oluyor da ICategoryService interface’inden field örneklediğimde EfCategoryDal’a kadar ulaşabiliyorum?

Def 3 1

Bunu bize, .Net Core ile gelen Program.cs dosyasına eklediğimiz kodlar sağlamaktadır. Alttaki kodlara baktığımızda, Registration dediğimiz işlemi görüyoruz. Burda “interface,class” ilişkisi belirtilmekte. Tam olarak da bizim sorduğumuz sorunun cevabı burda verilmektedir. ICategoryService CategorManager’ı çağırmaktadır, CategoryManager sınıfı içerisinde Dependency Injection ile örneklediğimiz ICategoryDal field’ı da EfCategoryDal’ı çağırmaktadır. Bu arka planda otomatik olarak sağlanmaktadır.

Def 1

Eğer yarın bir gün EntityFramework’ten vazgeçip farklı bir ORM aracı kullanılmak istendiğinde mesela Dapper veya NHibernate kullanılmak istenirse Dependency Injection kullandığımız için ICategoryDal interface’inden miras alan tüm ORM araçlarına rahatlıkla geçiş yapabiliriz. Bize bu esnekliği sağlayan tamamen Dependency Injection’dır.

Sonuç olarak, Dependency Injection yalnızca koda şıklık katmaz; aynı zamanda yazılımın ömrünü uzatan, onu esnek ve geleceğe hazır hale getiren bir yaklaşım sunar. Bugün Entity Framework kullanıyor olabilirsiniz, yarın Dapper’a geçebilirsiniz, belki de bir API’den veri çekmeniz gerekecek. DI sayesinde bu geçişler, kodu yerle bir etmeden gerçekleşebilir.

Yazılımda bağımlılığı azaltmak, aslında hayatta bağımlılığı azaltmak gibidir, ne kadar özgürseniz, o kadar rahat hareket edersiniz. Eğer siz de projelerinizde hâlâ new EfCategoryDal() gibi katı bağımlılıklarla yaşıyorsanız, belki de artık “yeni bir yolculuğa çıkma” zamanı gelmiştir.

Bu yazı sende ne reaksiyon verdi ?
  • _tt_
    Üşüttü
    0
  • sabr_m_zorlad_
    Sabrımı Zorladı
    0
  • ayd_nlatt_
    Aydınlattı
    0
  • rahatlatt_
    Rahatlattı
    2
  • mutlu_etti
    Mutlu Etti
    0
15 Puan

A code enthusiast and passionate software developer

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir