Macro aerosol::define_context
source · macro_rules! define_context {
($($input:tt)*) => { ... };
}
Expand description
Define a new context. Typically used at the top level of an application to contain the full set of requried dependencies.
Contexts follow a struct-like syntax, although the names of fields are for the most part unimportant.
Contexts automatically implement all applicable interfaces. An interface is applicable if all of the dependencies required by that interface are present in the context.
Dependencies are identified by type, not by the field name. Contexts may not contain two fields of the same type. Instead use new-type wrappers to distinguish similar dependencies.
Types used in a context must implement Clone + Debug
, and
Clone
should be a cheap operation. For this reason it is usual
to wrap dependencies in an Rc
or Arc
.
A constructor function will be automatically implemented for contexts, with one parameter for each dependency, to be provided in the same order as when the context is defined.
Example
use std::sync::Arc;
#[derive(Debug)]
struct Foo;
#[derive(Debug)]
struct Bar;
aerosol::define_context!(
TestContext {
foo: Arc<Foo>,
bar: Arc<Bar>,
}
);
fn main() {
TestContext::new(
Arc::new(Foo),
Arc::new(Bar),
);
}
It is also possible to define a factory type to enable dependencies to be automatically created.
When a factory is specified for a dependency, it will be
omitted from the parameter list required by the context’s
constructor. Instead, the constructor will call the build
method on the specified factory.
To conditionally use a factory, or use different factories for the same dependency, define separate contexts, or call the factory manually and pass the result to the context’s constructor in the normal way.
Example
use std::sync::Arc;
use failure;
#[derive(Debug)]
struct Foo;
#[derive(Debug)]
struct Bar;
struct FooFactory;
impl aerosol::Factory for FooFactory {
type Object = Arc<Foo>;
fn build() -> Result<Arc<Foo>, failure::Error> { Ok(Arc::new(Foo)) }
}
aerosol::define_context!(
TestContext {
foo: Arc<Foo> [FooFactory],
bar: Arc<Bar>,
}
);
fn main() {
TestContext::new(
Arc::new(Bar),
);
}