#[component]Expand description
Declares a component that may be used to instantiate types.
§Usage
#[component(...)] may be placed on a trait specifying functions that can later be used to retrieve instances.
It may contain definitions of so-called bindings and their dependencies.
The macro results in the generation of a type providing a builder for an implementation of the trait, whose name is prefixed by Dirk.
use dirk_framework::component; /// Required by `#[component(...)]`
#[component(
// ... (bindings)
)]
trait AComponent {
// ... (binding `fn`s)
}
/// Required when using a `Component`
use dirk_framework::component::Component;
use dirk_framework::component::builder::Builder;
/// 1. Via a type-safe builder
let component = DirkAComponent::builder() // prefix `Dirk` !!!
// .<...>(...) (provide instance bindings here)
.build();
/// 2. ... or using the `create` function, in case no instance bindings are specified
use dirk_framework::component::StaticComponent;
let component = DirkAComponent::create(); // prefix `Dirk` !!!
// Invoke binding `fn`s to retrieve instances, e.g.,
// let foo = component.<...>();§Bindings
A binding consists of four parts:
- a name
- a binding specifier (e.g.,
static_bind(...)orcloned_instance_bind(...)) - a type
- (optional) dependencies, e.g.
[a_binding, b_binding, c_binding]
#[component(
name: cloned_instance_bind(&'static str),
user_service: scoped_bind(UserService),
auth_service: scoped_bind(AuthService),
application: static_bind(Application) [name, user_service, auth_service]
)]
// ^ ^ ^ ^ ^ ^ ^ ^
// |_ name _| |specifier| |_ type _| |____ dependencies ____|
trait ApplicationComponent {
fn user_service(&self) -> std::rc::Rc<std::cell::RefCell<UserService>>;
fn auth_service(&self) -> std::rc::Rc<std::cell::RefCell<AuthService>>;
fn application(&self) -> Application;
}If a binding is supposed to be queried, a corresponding function needs to be specified in the trait.
In case a binding acts only as a dependency for other bindings, such a function can be omitted.
§Static bindings
static_bind(T) may be used to declare a static binding of type T.
§Scoped bindings
scoped_bind(T) may be used to declare a scoped binding of type Rc<RefCell<T>>.
§Singleton bindings
singleton_bind(T) may be used to declare a singleton binding of type Arc<RwLock<T>>.
§Cloned instance bindings
cloned_instance_bind(T) may be used to declare a user-provided binding of type T where T: Clone + 'static, which is cloned every time it is queried or injected.
§Scoped instance bindings
scoped_instance_bind(T) may be used to declare a user-provided binding of type Rc<RefCell<T>> where T: + 'static, such that all queried or injected Rcs point to the same instance.