macro_rules! application {
(
$self:ident: $Provider:ident
$(init [
$($JobIterable:block,)*
$($Job:ty $(as $JobAs:ty)?),*$(,)?
])?
$(services [
$($SvcIterable:block,)*
$($Svc:ty $(as $SvcAs:ty)?),*$(,)?
])?
$(components [
$($Component:ty $(as $($CompAs:ty)|+)?),+$(,)?
])?
$(provided {
$($($Provided:ty),+: $logic:expr),+$(,)?
})?
) => { ... };
}
Expand description
Including a type here implements Provides
Struct definitions wrapped in the inject!
macro get a From
All the types provided here are instantiated separately each time they are needed. If you want to support a singleton pattern, you need to construct the singletons in the constructor for this type and wrap them in an Arc. Then you can provide them in the “provided” section by cloning the Arc.
Open the main readme to see the following example in context.
ⓘ
application! {
self: MyApp
// init jobs are types implementing `Job` with a `run_once` function that
// needs to run once during startup.
// - constructed the same way as a component
// - made available as a dependency, like a component
// - wrap in curly braces for custom construction of an iterable of jobs.
init [
InitJob
]
// Services are types with a `run_forever` function that needs to run for
// the entire lifetime of the application.
// - constructed the same way as a component
// - made available as a dependency, like a component
// - registered as a service and spawned on startup.
// - wrap in curly braces for custom construction of an iterable of
// services.
// - Use 'as WrapperType' if it needs to be wrapped in order to get
// something that implements `Service`. wrapping uses WrapperType::from().
services [
MyService,
JobToLoopForever as LoopingJobService,
]
// Components are items that will be provided as dependencies to anything
// that needs it. This is similar to the types provided in the "provides"
// section, except that components can be built exclusively from other
// components and provided types, whereas "provides" items depend on other
// state or logic.
// - constructed via Type::from(MyApp). Use the inject! macro on the
// type to make this possible.
// - Use `as dyn SomeTrait` if you also want to provide the type as the
// implementation for Arc<dyn SomeTrait>
components [
Component1,
Component2,
DatabaseRepository as dyn Repository,
]
// Use this when you want to provide a value of some type that needs to either:
// - be constructed by some custom code you want to write here.
// - depend on some state that was initialized in MyApp.
//
// Syntax: Provide a list of the types you want to provide, followed by the
// expression that can be used to instantiate any of those types.
// ```
// TypeToProvide: { let x = self.get_x(); TypeToProvide::new(x) },
// Arc<dyn Trait>, Arc<ConcreteType>: Arc::new(ConcreteType::default()),
// ```
provided {
Arc<DatabaseConnectionPoolSingleton>: self.db_singleton.clone(),
}
}