Dependency injection for iOS/macOS/tvOS (Swift)
- Pure Swift Type Support
- Native
- Static typing
- Initializer/Property/Method Dependency Injections
- Object scopes as Single, LazySingle, PerScope, PerDependency, PerRequest (for UIViewController)
- Storyboard
- Registration/Resolve by type and name
- Registration/Resolve with parameters
- Enumeration registration and Default
- Circular Dependencies
- Registration by types, modules, assembly
- Fast resolve syntax
- Thread safety
- Scan Modules/Assemblies
Via CocoaPods.
pod 'DITranquillity'
Swift (iOS8+,macOS10.10+,tvOS9+) also need write in your PodFile use_frameworks!
Via Carthage.
protocol Animal {
var name: String { get }
}
class Cat: Animal {
init() { }
var name: String { return "Cat" }
}
let builder = DIContainerBuilder()
builder.register{ Cat() }
.asSelf()
.asType(Animal.self)
let scope = try! builder.build() // validate
let cat: Cat = try! scope.resolve()
let animal: Animal = try! scope.resolve()
print(cat.name) // Cat
print(animal.name) // Cat
protocol Animal {
var name: String { get }
}
class Cat: Animal {
init() { }
var name: String { return "CatName" }
}
class Dog: Animal {
init() { }
var name: String { return "DogName" }
}
class Pet: Animal {
let petName: String
init(name: String) {
petName = name
}
var name: String { return petName }
}
class Home {
let animals: [Animal]
init(animals: [Animal]) {
self.animals = animals
}
}
let builder = DIContainerBuilder()
builder.register{ Cat() }
.asSelf()
.asType(Animal.self)
.lifetime(.perDependency) // single, lazySingle, perScope, perRequest
builder.register(Dog.self)
.asSelf()
.asType(Animal.self)
.lifetime(.perDependency)
.initializer { Dog() }
builder.register{ Pet(name: "My Pet") }
.asSelf()
.asType(Animal.self)
.asDefault()
.lifetime(.perDependency)
builder.register(Home.self)
.asSelf()
.lifetime(.perScope)
.initializer { scope in return try! Home(animals: scope.resolveMany()) }
let scope = try! builder.build() // validate
let cat: Cat = try! scope.resolve()
let dog = try! scope.resolve(Dog.self)
let pet: Pet = *!scope
let animal: Animal = *!scope // default it's Pet
let home: Home = *!scope
print(cat.name) // CatName
print(dog.name) // DogName
print(pet.name) // My Pet
print(animal.name) // My Pet
print(home.animals) // [Dog, Cat, Pet]
let cat2: Cat = *!scope //cat2 !=== cat
let home2: Home = *!scope //home2 === home
Create your module:
class SampleModule: DIModule {
func load(builder: DIContainerBuilder) {
builder.register(vc: ViewController.self)
.dependency { (scope, obj) in obj.inject = *!scope }
}
}
Create your ViewController:
class ViewController: UIViewController {
internal var inject: Inject?
override func viewDidLoad() {
super.viewDidLoad()
print("Inject: \(inject)")
}
}
Registrate Storyboard:
func applicationDidFinishLaunching(_ application: UIApplication) {
window = UIWindow(frame: UIScreen.main.bounds)
let builder = DIContainerBuilder()
builder.register(module: SampleModule())
let container = try! builder.build()
let storyboard = DIStoryboard(name: "Main", bundle: nil, container: container)
window!.rootViewController = storyboard.instantiateInitialViewController()
window!.makeKeyAndVisible()
return true
}
Create your ViewController:
class ViewController: NSViewController {
internal var inject: Inject?
override func viewDidLoad() {
super.viewDidLoad()
print("Inject: \(inject)")
}
}
Registrate Storyboard:
func applicationDidFinishLaunching(_ aNotification: Notification) {
let builder = DIContainerBuilder()
builder.register(module: SampleModule())
let container = try! builder.build()
let storyboard = DIStoryboard(name: "Main", bundle: nil, container: container)
let viewController = storyboard.instantiateInitialController() as! NSViewController
let window = NSApplication.shared().windows.first
window?.contentViewController = viewController
}
iOS 8.0+,macOS 10.10+,tvOS 9.0+; ARC
- Swift 3.0: Xcode 8.0; version >= 0.9.5
- Swift 2.3: Xcode 7.0; version < 0.9.5
See CHANGELOG.md file.