Dependency Injection Nedir? Unity’de ve Zenject ile Kullanımı

Merhaba! 👋
Eğer oyun geliştirme ile ilgileniyorsanız veya yazılım dünyasında daha sağlam adımlar atmayı planlıyorsanız, bir noktada Dependency Injection (DI) kavramıyla karşılaşmanız kaçınılmaz.
Peki, bu kavram tam olarak ne anlama geliyor ve özellikle Unity projelerinde nasıl kullanılabiliyor?

Bu yazıda, Dependency Injection‘ın ne olduğunu, neden önemli olduğunu ve Unity’de Zenject gibi araçlarla nasıl hayata geçirildiğini birlikte keşfedeceğiz! 🚀

Dependency Injection (DI) Nedir?

Öncelikle, Dependency Injection’ın temelini anlayalım:
Bir sınıfın çalışabilmesi için başka bir sınıfa ihtiyaç duymasına bağımlılık denir.
Eğer bu bağımlılık, sınıfın içinde kendiliğinden oluşturulmak yerine dışarıdan sağlanıyorsa, işte buna Dependency Injection denir.

Bu yöntem sayesinde:

  • Kodlar daha modüler olur,

  • Birimleri bağımsız geliştirmek ve test etmek kolaylaşır,

  • Yazılımın bakımı ve geliştirilmesi daha pratik hale gelir.

Küçük Bir Örnek:

Sıkı bağlılık (tight coupling) örneği:

 public class Player : MonoBehaviour
{
    private Gun gun = new Gun(); // Bağımlılığı içeride oluşturduk
}

Bu yapı Player’ı doğrudan Gun sınıfına bağımlı yapar.
Halbuki Dependency Injection ile daha esnek bir tasarım elde edebiliriz:

 public class Player : MonoBehaviour
{
    private Gun gun;

    public Player(Gun injectedGun)
    {
        gun = injectedGun;
    }
}


Artık Player sınıfı, Gun sınıfını kendisi oluşturmuyor, dışarıdan alıyor!

DI Türleri: Constructor, Method ve Property Injection

DI’nin üç farklı türü vardır: Constructor Injection, Method Injection ve Property Injection. Bunları daha iyi anlamanız için her birini kısaca açıklayayım:

1.Constructor Injection: Bir sınıfın bağımlılıkları, sınıfın constructor’ı (yapıcı metodu) aracılığıyla dışarıdan sağlanır. Bu, en yaygın kullanılan DI türüdür.

 public class Player
{
    private IWeapon _weapon;

    // Constructor Injection
    public Player(IWeapon weapon)
    {
        _weapon = weapon;
    }
}

2.Method Injection: Bağımlılık, sınıfın bir metoduna parametre olarak geçirilir. Bu, özellikle yalnızca belirli bir metotta kullanılan bağımlılıklar için uygundur.

 public class Player
{
    public void UseWeapon(IWeapon weapon)
    {
        // Method Injection
        weapon.Use();
    }
}

3.Property Injection: Bu türde bağımlılık, sınıfın özelliklerine (property) dışarıdan atanır. Bu, daha esnek bir yapı sağlasa da genellikle daha az tercih edilir.

 public class Player
{
    public IWeapon Weapon { get; set; }

    // Property Injection
}

Unity’de Zenject ile Dependency Injection

Unity’de MonoBehaviour sınıflarının kendi constructor’ları olmadığı için klasik DI doğrudan uygulanamaz.
İşte tam burada Zenject devreye giriyor!

Zenject, Unity için geliştirilmiş güçlü bir Dependency Injection kütüphanesidir.

“Container” adını verdiği bir yapı ile bağımlılık yönetimini üstlenir.

Zenject ile Nasıl Kullanılır?

1. Bağlantıları Tanımlamak (Installer)

 

Zenject ile bağımlılıkları InstallBindings metodunda tanımlarız:

 public class GameInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind().To().AsTransient();
        Container.Bind().AsSingle();
    }
}
  • To<T>() → hangi sınıfı kullanacağını belirler.

  • AsTransient() → her çağrıldığında yeni bir nesne oluşturur.

  • AsSingle() → tüm proje boyunca aynı nesneyi kullanır (Singleton gibi davranır).

2.Bağımlılıkları Enjekte Etmek: Zenject, Inject özelliğini kullanarak bağımlılıkları otomatik olarak sınıfına enjekte eder. Mesela, bir Player sınıfında IWeapon bağımlılığını Zenject ile şöyle alabiliriz:

public class Player : MonoBehaviour
{
    [Inject]
    private IWeapon _weapon;

    void Start()
    {
        _weapon.Use();
    }
}

DI ve Test Edilebilirlik

DI’nin en büyük avantajlarından biri, test edilebilirlik sağlamasıdır. Çünkü bir sınıfın bağımlılıklarını dışarıdan alması, bu sınıfı daha bağımsız ve izole hale getirir. Bu sayede, birim testleri yazarken bağımlılıkları mock’lamak çok daha kolay olur.

 

Eğer DI kullanarak bağımlılıkları dışarıdan sağlarsak, bu bağımlılıkları test ederken sınıfı doğrudan etkilemeden test edebiliriz. Örneğin, IWeapon’ı bir mock sınıfı ile test edebiliriz:

[Test]
public void TestPlayerWeapon()
{
    var weaponMock = new Mock();
    var player = new Player(weaponMock.Object);
    
    player.UseWeapon();
    
    weaponMock.Verify(w => w.Use(), Times.Once);
}

Not:
Mock nesneler, gerçek nesnelerin yerine geçerek onların davranışını taklit eder.
Verify metodu, bir fonksiyonun kaç kez çağrıldığını kontrol eder.

Zenject Kullanmanın Avantajları ✨

  • Kodlar arasında gevşek bağlılık (loose coupling) sağlanır.

  • Tek Sorumluluk Prensibi (Single Responsibility Principle) kolayca uygulanır.

  • Scriptler arasında doğrudan referans kalmaz.

  • Tüm sahne referansları Installer içinde yönetilir.

  • İsim değişikliklerinde referanslar kırılmaz.

  • Daha az MonoBehaviour kullanımı sayesinde performans artışı sağlanır.

  • Singleton ihtiyacı ortadan kalkar.

  • Kolayca Unit Test yazabilirsiniz.

  • Zenject Kullanmanın Dezavantajları ⚡

    • Debug süreci zorlaşabilir (Inspector’da referansları doğrudan göremeyebilirsiniz).

    • Prototipleme süreci yavaşlayabilir (hızlı fikir denemelerinde DI kurmak zaman alır).

    • Inspector’da değişken açmak için ekstra kod yazmak gerekebilir.

    • Başlangıçta öğrenme eğrisi olabilir.

    • ECS (Entity Component System) yapıları ile doğrudan uyumlu değildir.
      (ECS: Performans odaklı veri düzeni sağlayan yeni nesil Unity mimarisidir.)

    • Zenject’in geliştirilme hızı son zamanlarda yavaşlamış gibi görünüyor.

  • Sonuç

    Dependency Injection, yazılım projelerinde esneklik, sürdürülebilirlik ve test edilebilirlik sağlayan vazgeçilmez bir tekniktir.
    Unity gibi oyun motorlarında Zenject gibi araçlar sayesinde DI prensiplerini başarılı şekilde uygulayabiliriz.

    Kendi projelerinde DI kullanarak:

    • Kod yapını sadeleştirebilir,

    • Test süreçlerini kolaylaştırabilir,

    • Uzun vadede daha sağlam oyunlar geliştirebilirsin! 🎮

    Eğer Zenject hakkında daha fazla bilgi edinmek istersen, Zenject Resmi Dökümantasyonu üzerinden veya küçük projelerde denemeler yaparak pratik kazanabilirsin.

    Mutlu kodlamalar! ✨

Bir Yanıt Bırakın

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