-
Notifications
You must be signed in to change notification settings - Fork 3
Container Inheritance
It's very common situation for a complex app to have two or even more containers. In this case it'd become necessary to organise an inheritance so a service from one container "sees" a service from another one.
Saber provides such inheritance via the @saber.dependsOn(OneContainer, AnotherContainer, ...)
annotation. As you can see from the annotation signature it's a multiple inheritance.
Imagine two containers:
// @saber.container(AppContainer)
// @saber.scope(App)
protocol AppContaining {}
// @saber.container(UserContainer)
// @saber.scope(User)
// @saber.dependsOn(AppContainer)
protocol UserContaining {}
Let's create a Database
service and attach it to the AppContainer
. It provides a functionality of getting a User
by an id
from its underlying storage:
// @saber.scope(App)
// @saber.cached
// ^ It's cached to be reusable across the app
class Database {
func user(id: String) -> User {
return User()
}
}
Then advance the UserContainer
to be able to get configured with a user id. Let's do it via externals. Also we use a trick to provide an internal Swift type as a dependency here.
typealias UserId = String // the trick
// @saber.container(UserContainer)
// @saber.scope(User)
// @saber.dependsOn(AppContainer)
// @saber.externals(UserId)
// ^ HERE!
protocol UserContaining {}
Let's add a UserManager
service to provide a current user:
// @saber.scope(User)
// @saber.cached
class UserManager {
let currentUser: User
// @saber.inject
// - `database` will be taken from the `AppContainer`
// - `userId` will be taken from the `UserContainer` external
init(database: Database, userId: UserId) {
self.currentUser = database.user(id: userId)
}
}
Now we can use our containers:
let appContainer = AppContainer()
// ...
let currentUserId = ...
let userContainer = UserContainer(appContainer: appContainer, userId: currentUserId)
print(userContainer.userManager.currentUser)
- User's Guide
- Advanced