Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/aryaxt/swiftinjection
Dependency Injection framework for Swift
https://github.com/aryaxt/swiftinjection
dependency-injection ioc ioc-container swift
Last synced: about 1 month ago
JSON representation
Dependency Injection framework for Swift
- Host: GitHub
- URL: https://github.com/aryaxt/swiftinjection
- Owner: aryaxt
- License: other
- Created: 2016-04-24T07:18:36.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2017-10-07T17:38:56.000Z (about 7 years ago)
- Last Synced: 2024-10-31T15:57:13.389Z (about 2 months ago)
- Topics: dependency-injection, ioc, ioc-container, swift
- Language: Swift
- Homepage:
- Size: 83 KB
- Stars: 22
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: License.txt
Awesome Lists containing this project
README
# SwiftInjection
[![Build Status](https://api.travis-ci.org/aryaxt/SwiftInjection.svg)](https://api.travis-ci.org/aryaxt/SwiftInjection)
[![Version](http://cocoapod-badges.herokuapp.com/v/SwiftInjection/badge.png)](http://cocoadocs.org/docsets/SwiftInjection)A dependency container for Swift
#### Setting up Dependencies
A Module file is where you define your dependencies. The goal is to abstract out all your dependencies in this file. The only class in your project that should know about concrete implementations should be the module class, the rest of the classes in your application should be using these implementations through interfaces.
You could have multiple module classes in order to organize your dependencies
```swift
public class AppModule: DIModule {
public func load(container: DIContainer) {
container.bind() { UserDefaults.standard() }
container.bind() { URLSession.shared() }
container.bind(type: HttpService.self) { HttpClient(baseUrl: "https://api.github.com", urlSession: $0)) }
container.bind(type: GithubService.self) { GithubHttpClient(httpService: $0) }
container.bind(type: AnalyticsTracker.self, named: GoogleAnalyticsTracker.analyticsIdentifier()) { GoogleAnalyticsTracker() }
container.bind(type: AnalyticsTracker.self, named: AmplitudeAnalyticsTracker.analyticsIdentifier()) { AmplitudeAnalyticsTracker() }
}
}class AppDelegate: UIResponder, UIApplicationDelegate {
override init() {
super.init()
DIContainer.instance.addModule(AppModule())
}
}
```#### Binding Internal classes
avoid direct use of singletons to make your code more testable
```swift
container.bind() { URLSession.shared() }
```
#### Binding classes as singleton
Instead of adding singleton logic to your classes simply bind them as singleton
Note: Structs are not compatible with singleton pattern
```swift
// Bind class as singleton
bind(asSingleton: true) { Session() }// Bind protocol to an implementation as singleton
bind(AnalyticsTracker.self, asSingleton: true) { GoogleAnalyticsTracker() }
```
#### Bind Named Instances
In cases where you have multiple implementations for a single protocol you can use named binding to retrieve the correct instance
```swift
bind(AnalyticsTracker.self, named: "Google") { GoogleAnalyticsTraker() }
bind(AnalyticsTracker.self, named: "Amplitude") { AmplitudeAnalyticsTracker() }// Inject expected instance
let googleAnalyticsTracker: AnalyticsTracker = inject(named: "Google")
let amplitudeAnalyticsTracker: AnalyticsTracker = inject(named: "Amplitude")// Get all implementations for a given protocol (great for chain of responssibilities)
let trackers: [AnalyticsTracker] = injectAll()
```#### Property Injection
Only use property injection on root level, for anything else below the viewController use constructor injection
```swift
class ViewController: UIViewController {
let githubService: GithubService = inject() // Injects the implementation defined in module
let session = inject(Session.self) // injects the singleton instance
let analyticTrackers: [AnalyticsTracker] = injectAll() // Injects all implemetations of AnalyticsTracker
}
```#### Constructor Injection
Simpy pass dependencies through the intiializer and define binding in the module file
```swift
protocol GithubService { }protocol HttpService { }
class GithubHttpClient: GithubService {
let httpService: HttpService
// Constructor injection
init(httpService: HttpService) {
self.httpService = httpService
}
}class AppModule: DIModule {
func load(container: DIContainer) {
container.bind(type: URLSession.self) { URLSession.shared() }
container.bind(type: HttpService.self) { HttpClient(baseUrl: "https://api.github.com", urlSession: $0)) }
container.bind(type: GithubService.self) { GithubHttpClient(httpService: $0) }
}
}class ViewController: UIViewController {
// Property Injection
// This will return an instance of GithubHttpClient with all depndencies as defined in module
let githubService: GithubService = inject()
}
```