← Back to list

Dependency Injection — Swift

Yazılım projeleri büyüdükçe sınıflar arasındaki bağımlılıklar artar. Bağımlılık, bir sınıfın çalışabilmesi için başka bir sınıfa ihtiyaç…

Esra Türk · 2024-10-31 09:14 · 15 claps · 2.7 min read
#dependency-injection #constructor-injection #method-injection #swi̇ft #ios-development
Open on Medium ↗
Wiki topics: 📱 · Mobile Development

Dependency Injection — Swift

Yazılım projeleri büyüdükçe sınıflar arasındaki bağımlılıklar artar. Bağımlılık, bir sınıfın çalışabilmesi için başka bir sınıfa ihtiyaç duymasıdır. Örneğin veri tabanına erişmek isteyen bir sınıf, bir veri tabanı bağlantı sınıfına bağımlıdır.Bağımlılıklar kodun karmaşıklaşmasına, test edilebilirliğin ve değişiklik yapmanın zorlaşmasına neden olabilir.

Görsel Kaynak

Görsel Kaynak

Dependency injection nedir?

Dependency Injection(DI), sınıflar arasındaki bağımlılıkları çözmek için kullanılan bir tasarım desenidir. DI bir sınıfın ihtiyaç duyduğu nesneleri kendi gövdesinde(class body) oluşturmak yerine dışarıdan almasını sağlar. Böylece sınıflar arasındaki bağımlılıklar azalır. Kod daha modüler, test edilebilir ve değişikliklere açık hale gelir.

DI, dört yöntemle gerçekleştirilir:

  • Constructor Injection: Bir nesne oluşturulurken bağımlılıklar initializer parametresi olarak verilir. En yaygın ve tercih edilen yöntemdir.
  • Property Injection: Bağımlılıklar, nesne oluşturulduktan sonra public olarak tanımlanmış özelliklere atanır.
  • Method Injection: Bağımlılıklar, nesnenin bir metodu aracılığıyla verilir. Bu yöntem daha az tercih edilir ve diğer yöntemlere göre daha az esnektir.
  • Interface Injection: Bağımlılıklar protocol aracılığıyla verilir. Soyut bir bağımlılık yönetimi sağlar ve büyük ölçekli uygulamalarda tercih edilir.

Görsel kaynak

Görsel kaynak

Bu yazıda DI yöntemlerini, oluşturduğum Service ve LoggingService sınıfları üzerinden inceleyeceğiz.

class Service {
    func performServiceAction() {
        print("Service action performed")
    }
}

class LoggingService {
    func performLoggingAction() {
        print("Logging action performed")
    }
}

Dependency Injection Olmadan

class ViewModel {
    private let service: Service?
    private let loggingService: LoggingService?

    init() {
        self.service = Service()
        self.loggingService = LoggingService()
    }

    func execute() {
        service.performServiceAction()
        loggingService.performLoggingAction()
    }
}

let viewModel = ViewModel()
viewModel.execute()

Viewmodel nesnesi oluşturulurken Service ve LoggingService nesneleri otomatik olarak oluşturuluyor. ViewModelin çalışabilmesi için bu servislerin mutlaka mevcut olması gerekiyor.Bu durum ViewModel sınıfını servislere bağımlı hale getiriyor.

Constructor Injection

class ViewModel {
    private let service: Service
    private let loggingService: LoggingService

    init(service: Service, loggingService: LoggingService) {
        self.service = service
        self.loggingService = loggingService
    }

    func execute() {
        service.performServiceAction()
        loggingService.performLoggingAction()
    }
}

let service = Service()
let loggingService = LoggingService()
let viewModel = ViewModel(service: service, loggingService: loggingService)
viewModel.execute()

Bağımlılıklar nesne oluşturulurken dışarıdan veriliyor ve nesne bu bağımlılıklarla birlikte çalışmaya hazır hale geliyor. Farklı bir servis kullanmak istersek sadece bağımlılığı değiştirmemiz yeterli olacaktır.

Property Injection

class ViewModel {
    var service: Service?
    var loggingService: LoggingService?

    func execute() {
        service?.performServiceAction()
        loggingService?.performLoggingAction()
    }
}

let viewModel = ViewModel()
viewModel.service = Service() // Bağımlılık dışarıdan veriliyor
viewModel.loggingService = LoggingService() // Bağımlılık dışarıdan veriliyor
viewModel.execute()

Property Injection yönteminde bağımlılıkların dışarıdan verilmesi gerektiği için unutulursa nil hatalarıyla karşılaşılabilir. Bu da ek bir dikkat gerektirir.

Method Injection

class ViewModel {
    func execute(service: Service, loggingService: LoggingService) {
        service.performServiceAction()
        loggingService.performLoggingAction()
    }
}

let service = Service()
let loggingService = LoggingService()
let viewModel = ViewModel()
viewModel.execute(service: service, loggingService: loggingService)

Sınıfın ihtiyaç duyduğu bağımlılıkları bir metodun parametresi olarak alır ve o metodun kapsamında bu bağımlılıklara erişmesini sağlar. Aynı metodun farklı çağrılarında farklı bağımlılıklar kullanmak istenirse tercih edilebilir.Metod fazla parametre alıyorsa kod karmaşıklığına sebep olabilir.

Interface Injection

protocol DependencyInjectable {
    func injectService(service: Service)
    func injectLoggingService(loggingService: LoggingService)
}

class ViewModel: DependencyInjectable {
    private var service: Service?
    private var loggingService: LoggingService?

    func injectService(service: Service) {
        self.service = service
    }

    func injectLoggingService(loggingService: LoggingService) {
        self.loggingService = loggingService
    }

    func execute() {
        service?.performServiceAction()
        loggingService?.performLoggingAction()
    }
}

let service = Service()
let loggingService = LoggingService()
let viewModel = ViewModel()

// Interface Injection ile bağımlılıkları enjekte ediyoruz
viewModel.injectService(service)
viewModel.injectLoggingService(loggingService)

viewModel.execute()

DependencyInjectable protocolü bağımlılıkların enjekte edilmesini sağlayan iki temel metodu tanımlar: injectService ve injectLoggingService. Bu metotlar Service ve LoggingService türünde nesneler alır.

ViewModel sınıfına injectService ve injectLoggingService metotları aracılığıyla gerekli servisler verilerek ViewModel’in farklı senaryolarda farklı servislerle çalışması sağlanır.

Sınıflar farklı servislerle çalışabileceği için kod daha genel amaçlı hale gelir ve uygulamada değişiklik yapmak kolaylaşır.

Sonuç

Dependency injection yöntemlerinin doğru seçimi, kodun kalitesi, bakımı ve test edilebilirliği üzerinde önemli bir etkiye sahiptir. Projenizin ihtiyaçlarına en uygun yöntemi seçerek daha iyi sonuçlar elde edebilirsiniz.

Zaman ayırdığınız ve okuduğunuz için teşekkür ederim.

Kaynakça

cocoacasts: Dependency Injection in Swift

Needone.app: Dependency Injection

Wikipedia: Dependency Injection


메타데이터
post_id
e72d8b963a2f
slug
dependency-injection-swift-e72d8b963a2f
url
https://medium.com/@esraturk/dependency-injection-swift-e72d8b963a2f
canonical_url
https://medium.com/@esraturk/dependency-injection-swift-e72d8b963a2f
author_url
https://medium.com/@esraturk
status
ok
fetched_at
2026-07-09 10:05:04