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),
    );
}