Apodidae
Apodidae copied to clipboard
Swift dependency Injection Framework
Apodidae
Swift Dependency Injection Framework
With Swift 2.0 and this talk from Apple, protocol oriented programming has now arrived on the Cocoa scene. Although protocols allow for elegant decoupling of interface from implementation, a little extra glue (in the form of Dependecy Injection) cements the ideal of never having to know if your duck is actually a duck
Name
Apodidae is the taxonomic family of birds known as swifts in english. Is your swift a sooty swift or a lesser swallow tail swift? You don't care! that's why you're using dependency injection, obviously...
Usage
Have a protocol that needs filling? add Injectable to your implementation:
protocol Swift {
func airspeedVelocity() -> Int
}
struct WhiteThroatedNeedleTail: Swift, Injectable {
static func dependencies -> [Any.Type] {
return []
}
init(dependencies: DependencyContainer) {}
func airspeedVelocity() -> Int {
return 169
}
}
and register with the registrar:
import Apodidae
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// init application
...
registerDependencies()
}
func registerDependencies() -> Void {
let registrar = Registrar.instance
// NOTE: Implementation MUST implement the Injectable protocol
// NOTE: Currently registration is not type safe - you could register a nonconforming class, which will fail at runtime
registrar.register(Swift.self, WhiteThroatedNeedleTail.self)
}
}
Instances of your protocol can then be grabbed from the registrar:
struct Thingy {
let swift = Registrar.instance.obtain(Swift.self) as! Swift
func howFastAreMyBirds() -> Int {
return self.swift.airspeedVelocity()
}
}
But what if my dependencies have dependencies?? Apodidae will resolve the chained dependencies before providing you the implementation:
protocol BirdCage: Injectable {
func howFastAreMyBirds() -> Int
}
struct Thingy: BirdCage {
let swift: Swift
static func dependencies -> [Any] {
return [
Swift.self // defines the type dependency on a swift
]
}
init(dependencies: DependencyContainer) {
// Dependencies are returned in the same order you specified
self.swift = dependencies.extract(Swift.self)
}
func howFastAreMyBirds() -> Int {
return self.swift.airspeedVelocity()
}
}