-
Notifications
You must be signed in to change notification settings - Fork 3
Lazy Injections
apleshkov edited this page Aug 12, 2018
·
4 revisions
There're some cases when you want to get a dependency on demand. For example it's too "heavy" to create, so you don't want to slow your app launch.
Saber considers any injection as lazy if it's a lambda with a return value and no arguments:
() -> Dependency
Every type of injection supports laziness.
// @saber.scope(App)
// @saber.cached
class UserStorage {
init() {
// very heavy initialization
}
}
// @saber.scope(App)
class UserManager {
// @saber.inject
// It's better to inject via initializer,
// but we use a property injection here
// for the sake of demonstration how to
// use lazy + force unwrapping
var userStorage: (() -> UserStorage)!
func userName(id: String) -> String? {
// NOTE: UserStorage is *cached* (see above), so
// we don't need to store its instance here
return userStorage().user(id: id).name
}
}
Note that containers inject lazy dependencies as { [unowned self] in return self.dependency }
, so please be careful.
It's possible to simplify your lazy injections with a typealias
.
To "tell" Saber about such type alias, you provide its name via a configuration:
lazyTypealias: LazyInjection
Then define it in your code like:
typealias LazyInjection<T> = () -> T
Saber will consider T
as a service to inject lazily:
// @saber.scope(App)
class Foo {
// @saber.inject
var baz: LazyInjection<Baz>!
// @saber.inject
init(bar: LazyInjection<Bar>) { ... }
}
- User's Guide
- Advanced