Swinject, iOS uygulamalarında Dependency Injection modelini uygulayan Swift için bir DI konteyneridir. Framework, bağımlılıkların oluşturulmasını ve enjeksiyonunu otomatikleştirerek manuel nesne ve fabrika yönetimini ortadan kaldırır. GitHub'da Swinject'e göre, kütüphane Constructor Injection, Property Injection ve Method Injection'ı esnek bir scope sistemiyle yaşam döngüsü yönetimi için destekler.
Önemli Noktalar
Swinject, iOS, macOS ve watchOS için uygulamalarda bağımlılık enjeksiyonunu basitleştirmek üzere tasarlanmış Swift dili için açık kaynaklı bir DI konteyneridir. Framework, Service Locator yaklaşımını kullanır: hizmetler merkezi bir konteynere kaydedilir ve bir örnek istendiğinde konteyner bağımlılık grafiğini otomatik olarak çözer.
Dependency Injection (DI), bir nesnenin bağımlılıklarını dahili olarak oluşturmak yerine dışarıdan aldığı bir tasarım modelidir. Bu, bileşenler arasındaki bağımlılığı azaltır, birim testini basitleştirir ve tüketici kodunu değiştirmeden uygulamaların değiştirilmesine olanak tanır.
Martin Fowler'a (2004) göre DI, Inversion of Control'ün belirli bir durumudur ve kurucu, özellik veya yöntem enjeksiyonu yoluyla uygulanır. Swinject bu süreci otomatikleştirerek fabrikaları ve hizmet bulucuları manuel olarak yazma ihtiyacını ortadan kaldırır.
Swinject'i, çapraz bağımlılıkları olan üç veya daha fazla hizmete sahip projelerde kullanın; burada manuel nesne oluşturma, başlatma kodunun şişmesine ve test edilebilirliğin azalmasına yol açar.
Swinject, Apple ekosistemiyle sıkı bir şekilde entegre olur ve Swift 3.0'dan itibaren tüm Swift sürümlerini destekler. Framework, köprüler aracılığıyla Objective-C ile uyumludur ve tam kod taşıması olmadan mevcut karma dil projelerine dahil edilmesine olanak tanır. Bu, özellikle beş yıldan fazla geliştirme geçmişine sahip büyük uygulamalar için önemlidir.
Swinject konteyneri, kayıtlı hizmetlerin kaydını saklayan Container sınıfı tarafından uygulanır. resolve yöntemi çağrıldığında, konteyner bir nesne oluşturur ve kayıt grafiği aracılığıyla tüm bağımlılıklarını yinelemeli olarak çözer.
Container, soyutlamalar ve uygulamaları arasındaki eşlemelerin kaydedildiği merkezi nesnedir. Service, bir sözleşme tanımlayan protokoldür, Component ise bu protokolü uygulayan bir sınıftır. Kayıt, hizmet türünü ve bir fabrikayı alan register yöntemi kullanılarak yapılır.
let container = Container()
container.register(Networking.self) { _ in
NetworkService()
}
let service = container.resolve(Networking.self)
resolve yöntemi, belirtilen protokol için kaydedilmiş somut uygulamanın bir örneğini döndürür. Bir bağımlılık kayıtlı değilse, konteyner geliştirme sırasında sorunun hızlı tespiti için ölümcül bir hata fırlatır.
Her kayıt, bir fabrika işlevi ve seçili bir kapsam ile bir giriş oluşturur. Tek bir hizmet, farklı adlarla birden çok kayda sahip olabilir ve ada göre belirli bir uygulama seçilmesine olanak tanır — farklı ortamlar (geliştirme, hazırlık, üretim) için kullanışlıdır.
Bağımlılık çözme süreci yinelemeli olarak çalışır: konteyner bir Component örneği oluşturduğunda, başlatıcısını analiz eder ve her parametre için karşılık gelen türle resolve'u çağırır. Bir bağımlılığın kendi bağımlılıkları da varsa, tüm grafik tamamen oluşturulana kadar süreç devam eder. İç içe geçme derinliği yalnızca kullanılabilir bellek ile sınırlıdır, ancak pratikte nadiren beş seviyeyi aşar.
Swinject, her biri mimari bağlama bağlı olarak uygulanabilen üç ana bağımlılık enjeksiyon yöntemini destekler.
Constructor Injection, başlatıcı parametreleri aracılığıyla bağımlılıkları enjekte eder. Bu, bir nesnenin oluşturulduğu andan itibaren her zaman geçerli durumda olmasını sağlayan tercih edilen yöntemdir. Swinject, kurucuya iletilen tüm bağımlılıkları otomatik olarak çözer.
class LoginViewModel {
private let authService: AuthProtocol
init(authService: AuthProtocol) {
self.authService = authService
}
}
container.register(AuthProtocol.self) { _ in
AuthService()
}
container.register(LoginViewModel.self) { r in
LoginViewModel(authService: r.resolve(AuthProtocol.self)!)
}
Property Injection, başlatma işleminden sonra nesne özelliklerini ayarlayarak bağımlılıkları enjekte eder. Bir bağımlılık isteğe bağlı olduğunda veya kurucu aracılığıyla iletilemediğinde kullanılır; örneğin, view controller'ın otomatik olarak oluşturulduğu Storyboard ile çalışırken. Swinject, açık bir resolve çağrısı olmadan çalışma zamanında otomatik özellik enjeksiyonu için @Inject ek açıklamasını destekler.
Property Injection kullanırken, bağımlılığın nesneye ilk erişimden önce ayarlandığından emin olmak önemlidir. Aksi takdirde, özellik nil kalır ve beklenmeyen bir çökmeye yol açar. Swinject, Implicitly Unwrapped Optional mekanizması ve bağımlılık grafiği çözme aşamasında sıkı doğrulama yoluyla bu sorunu çözer.
Method Injection, yöntem parametreleri aracılığıyla bağımlılıkları enjekte eder. Yalnızca tek bir işlemi gerçekleştirmek için gereken ve nesnenin kalıcı durumu olarak saklanmaması gereken hizmetler için kullanılır. Bu en az yaygın olan ancak geri çağırmalar için kullanışlı olan enjeksiyon yöntemidir.
ObjectScope, Swinject konteyneri içinde oluşturulan bir örneğin yaşam süresini belirleyen bir mekanizmadır. Framework, ObjectScopeProtocol aracılığıyla özel kapsamlar oluşturma yeteneği ile birlikte üç yerleşik kapsam sağlar.
graph kapsamı varsayılan değerdir. Her resolve çağrısı, yalnızca bağımlılık grafiği çözümü süresince yaşayan yeni bir örnek oluşturur. Önbelleğe almadan kaynaklanan bellek sızıntılarını ortadan kaldırdığından durumu olmayan hizmetler için güvenli bir seçimdir.
container kapsamı, konteyner içinde bir singleton'dur. Örnek, ilk resolve'da bir kez oluşturulur ve sonraki tüm isteklerde döndürülür. Paylaşılan duruma sahip hizmetler için uygundur: veri önbelleği, günlükçü, uygulama ayarları.
transient kapsamı, önbelleğe alma olmadan her resolve çağrısında yeni bir örnek oluşturur. Yeniden kullanılması gerekmeyen hafif nesneler için kullanılır — örneğin, belirli bir HTTP isteğini işleyen modüller.
| Kapsam | Yaşam Süresi | Önerilen Kullanım |
|---|---|---|
| graph | Grafik çözümü süresince | Varsayılan olarak durumsuz hizmetler |
| container | Konteynerin tüm yaşamı | Singleton: önbellek, günlükçü, ağ istemcisi |
| transient | Önbellek yok | Tek kullanımlık hafif nesneler |
Swinject'i gerçek bir iOS projesine entegre etmek, uygulama başlatıldığında konteynerin başlatılmasıyla başlar — AppDelegate veya sahnede. Kayıtların Assembly aracılığıyla yapılandırılması önerilir: ilgili hizmetleri gruplayan ayrı bir sınıf veya yapı.
Swift Developer Community anketine (2025) göre, iOS geliştiricilerinin %43'ü ticari projelerde ağ katmanı, depolar ve gezinme koordinatörlerinin bağımlılıklarını yönetmek için DI konteynerleri kullanmaktadır. Swinject, minimum sözdizimi ve Objective-C uyumluluğu sayesinde en popüler çözüm olmaya devam etmektedir.
Storyboard Injection, Swinject'in benzersiz bir özelliğidir: konteyner, AppDelegate'te ek kod olmadan Storyboard'dan oluşturulan view controller'lara otomatik olarak bağımlılıkları enjekte eder. Bu, init(container:) yöntemi aracılığıyla UIStoryboard'a iletilen ve view controller oluşturmayı yakalayıp kayıtlı bağımlılıkları enjekte eden özel bir çözücü kullanır.
Büyük projelerde Swinject, gezinme koordinatörleriyle birleştirilebilir: koordinatör konteyneri alır ve bağımlılıklarını resolve aracılığıyla çözerek ekranlar oluşturur ve tüm sahne için tek bir yapılandırma noktası sağlar.
Assembly mimarisi, kayıtları düzenlemek için önerilen modeldir. Her Assembly, ilgili hizmetleri gruplar (örneğin, NetworkingAssembly, DatabaseAssembly) ve diğer Assembly'lere bağımlı olabilir. Konteyner başlatılırken, tüm Assembly'ler yüklenir ve hizmetlerini kaydeder, net sorumluluk ayrımı sağlar ve düzinelerce hizmeti olan büyük projelerde DI yapılandırmasında gezinmeyi basitleştirir.
DI grafiğini hata ayıklamak için Swinject, bir plist dosyasından yapılandırma yükleyen SwinjectPropertyLoader uzantısını ve UIStoryboard'un özel bir sürümü aracılığıyla storyboard entegrasyonu olan SwinjectStoryboard'u sağlar. Bu araçlar, mevcut bir projeyi manuel nesne oluşturmadan DI'ya taşırken özellikle kullanışlıdır: geliştirici, ana özellik geliştirmeyi durdurmadan testler ve çözüm hata günlüğü aracılığıyla bağımlılık grafiğini kontrol ederek hizmetleri kademeli olarak kaydedebilir.
Swinject ayrıca, açık fabrika kaydı olmadan başlatıcı parametre türlerine dayalı otomatik bağımlılık çözümü için SwinjectAutoregistration uzantısı aracılığıyla RxSwift ve Combine ile entegrasyon sağlar. Bu, basit hizmetler için kayıt kodu miktarını azaltır: fabrika belirtmeden container.register(ServiceProtocol.self) çağrısı yapmanız yeterlidir ve Swinject, Swift çalışma zamanı tarafından sağlanan Signal yansımasına dayalı olarak fabrikayı otomatik olarak oluşturur. Bu yaklaşım, kurucuları yalnızca temel türleri kabul eden ve karmaşık oluşturma mantığı gerektirmeyen hizmetler için önerilir.
Sıkça Sorulan Sorular
Swinject kod oluşturma veya yansıma olmadan saf Swift ile yazılmıştır. Needle'ın aksine kaynak oluşturma gerektirmez ve Dip ile karşılaştırıldığında, mevcut UIKit projelerine entegrasyonu basitleştiren yerleşik Storyboard Injection desteği sağlar.
Xcode'da File — Add Packages menüsü aracılığıyla URL github.com/Swinject/Swinject ile paketi ekleyin. CocoaPods ve Carthage aracılığıyla kurulum da mevcuttur. Kurulumdan sonra Swinject modülünü içe aktarın ve bir Container örneği oluşturun.
Evet, Swinject SwiftUI ile tamamen uyumludur. Bağımlılıklar, konteynerin EnvironmentObject olarak iletildiği View başlatıcıları veya Environment aracılığıyla enjekte edilir. Swinject, UIKit'e bağımlı değildir ve her iki çerçeveyle de eşit şekilde çalışır.
Testler için ayrı bir konteyner oluşturun ve gerçek hizmetleri mock'larla değiştirin. Swinject, tüketici kodunu değiştirmeden kayıtları geçersiz kılmaya izin verir. Her test, minimum bağımlılık kümesiyle izole bir konteyner alır.
Analitik için container kapsamını kullanın, böylece tüm ekranlar tek bir örnek aracılığıyla olay gönderir. Bu, farklı tüketiciler arasında veri çoğaltması olmadan birleşik bir gönderme kuyruğu ve doğru toplu toplama işlemi sağlar.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun