Caner Tosuner

Leave your code better than you found it

Dependency Injection

Yazılımla ilgilenen kişiler bilirler ki proje geliştirmede süreçler çok önemlidir. Müşteriye gidilir, ihtiyaç olan şey dinlenir, analiz edilir ve analiz yazılıp müşteriye sunulur. Müşteri analizi kabul eder ve development süreci başlar. Analiz developera gelir ve 3 ay sonra işini bitirdikten sonra müşteriye projenin sunumu yapılır ve müşterinin çenesi o anda açılır. Bunu da ekleyelim, şunu da yapalım, bu da olsa daha iyi olur.. süreli olarak bu gibi cümleler duymamak hiçten bile değildir. Bu gibi durumları göz önüne alarak projeyi olabildiğince esnek hazırlamak yararımıza olacaktır.

Proje içerisindeki modüllerin bir birlerine gevşek bağlı(loosely coupled) olması, üstte bahsettiğimiz gibi sonradan oluşabilecek talepler için minimum efor sarf change request leri yani sonradan istenilen değişiklikleri hayata geçirmemize katkıda bulunabilir. Bir senaryo ele alalım;

Person ve Car adında classrımız olsun ve bu classların içerisinde Drive adında bir metodumuz olsun ve kullanıcı classının instance alınıp Drive metodu çağrıldığında kullanıcı Car classının Drive metodu çağrılarak araba kullanıyor olsun.

public class Person {
  private Car myCar = new Car();
 
  public void Drive()
  {
     this.myCar.drive();
  }
}

 

Müşterinin isteğine göre araba sürebilen bir Person objesi yaratmış olduk. Peki ya müşteri 2 ay sonra "bu person kamyonda sürsün, motorsiklette sürsün.." derse ? İşte bu gibi durumlar için üstte yazdığımız class işimizi görmicektir ve müşterinin istediğini geliştirmemiz belkide bu güne kadar ki development süresi kadar zaman alabilir de (projenin büyüklüğü gibi vs. konulara bağlı). Üstteki sorunumuz Person objesi Car objesine bağlı ve bu nedenle Bus ve Motorcycle classlarını Person objesine entegre etmemize engel oluyor. İşte Dependency Injection burda devreye giriyor. Amacımız Person objesinin bağımlılığını en aza indirgemek. Bunun için ilk olarak IVehicle adında içerisinde Drive metodu bulunan bir interface yazıyoruz.

public interface IVehicle {
  void Drive();
}

Sonrasında ise bizim Car, Bus ve Motorcycle class larımız IVehicle implemente etsinler

public class Car : IVehicle 
{
  public void Drive()
  {
    Console.WriteLn("Araba sürülüyor");
  }
}

public class Bus : IVehicle 
{
  public void Drive()
  {
    Console.WriteLn("Otobüs sürülüyor");
  }
}

public class Motorcycle: IVehicle 
{
  public void Drive()
  {
    Console.WriteLn("Motorsiklet sürülüyor");
  }
}

Yukarıda ki geliştirmeler ile birlikte artık Person class'ımızın Car Bus gibi objelere olan bağlılığını ortadan kaldırmış olduk yani birbirlerine gevşek bağlı(loosely coupled) halede getirdik diyebiliriz.

Person classımızın yeni hali aşağıdaki gibi olacaktır.

public class Person {
  private IVehicle vehicle {get; set;}

  public Person(IVehicle Vehicle)
  {
    this.vehicle = Vehicle
  }
 
  public void Drive()
  {
     this.vehicle.Drive();
  }
}

 

Person classımızı kullanacağımız yerde artık şu şekilde yazabiliriz;

//Araba sürmesini istediğimizde
var person=new Person(new Car());
person.Drive();

//Otobüs sürmesini istediğimizde
var person=new Person(new Bus());
person.Drive();

Burada IVehicle interfaceîni implemente eden sayısız nesne ekleyebiliriz veya bu nesneler üzerinde değişiklik yapabiliriz ancak bu durum Person classını hiç ilgilendirmiyor çünkü herhangi bir nesneye bağlı değildir.