Subcomponents
Scopes enforces an object to be a singleton within the component, so everyone can interact with the same instance. However there are times when we need multiple sets of such instances. For example, we might be implementing a web server, and there are a lot of shared resources with every session. We want the session to be independent, so we need to create component for each session:
impl Server {
pub fn new_session(url: Url) -> Session {
Session{
component: <dyn SessionComponent>::build({url,...})
}
}
}
However, there are also some resource that belongs to the whole server shared by all sessions, for
example, an IO bound thread pool. We have to rebind this in every SessionComponent
impl Server{
#[inject]
pub fn new(#[qualified(IoBound)] io_threadpool: &ThreadPool) { ... }
pub fn new_session(&self, url: Url) -> Session {
Session {
component: <dyn SessionComponent>::build({
url,
self.io_threadpool,
...
})
}
}
}
Managing these will soon get ugly.
Instead we can create
a #[subcomponent]
which can have
distinct scoped bindings, modules, but also has access to bindings in its parent component.
Using #[subcomponent]
is almost identical to a regular #[component]
, except that the
#[subcomponent]
has to be installed in a parent component, and the method to create an instance.
Installing a #[subcomponent]
A #[subcomponent]
is installed by first listing it in
a #[module]
using
the subcomponents
metadata
#[module(subcomponents: [MySubcomponent])]
impl ParentComponentModule {
Then installing the #[module]
in a parent component. The parent component can be either a regular
component or another subcomponent.
Creating a instance of the subcomponent
The #[module]
with a subcomponents: [FooSubcomponent]
metadata creates hidden binding
of Cl<FooSubcomponentBuilder>
which can be injected to create new instances of FooSubcomponent
by calling build()
. build()
also takes the
corresponding #[builder_modules]
if the subcomponent is defined with
the builder_modules
metadata
build
can be called multiple times to create independent subcomponents, with the parent being
shared.
Lifetime
The lifetime of the subcomponent is bound by its parent.
Examples
https://github.com/azureblaze/lockjaw/blob/main/tests/sub_component.rs