Macro runtime_injector::define_module[][src]

macro_rules! define_module {
    {
        $(
            $(#[$($attr:meta),*])*
            $key:ident = $value:tt
        ),*
        $(,)?
    } => { ... };
    (
        @provide $module:expr,
        services = [
            $($service:expr),*
            $(,)?
        ]
    ) => { ... };
    (
        @provide $module:expr,
        interfaces = {
            $($interface:ty = [
                $($implementation:expr),*
                $(,)?
            ]),*
            $(,)?
        }
    ) => { ... };
    (
        @provide $module:expr,
        arguments = {
            $($service:ty = [
                $($arg:expr),*
                $(,)?
            ]),*
            $(,)?
        }
    ) => { ... };
}
Expand description

Defines a new module using a domain specific language.

Example

use runtime_injector::{
    define_module, interface, Arg, Injector, IntoSingleton, IntoTransient,
    Svc,
};

struct Foo(Arg<i32>);
struct Bar();
struct Baz(Vec<Svc<dyn Fooable>>);
#[cfg(test)]
struct Quux();

trait Fooable: Send + Sync {}
impl Fooable for Foo {}
impl Fooable for Bar {}
interface! {
    dyn Fooable = [
        Foo,
        Bar,
        #[cfg(test)]
        Quux,
    ]
};

let module = define_module! {
    services = [
        Baz.singleton(),
    ],
    interfaces = {
        dyn Fooable = [
            Foo.singleton(),
            Bar.singleton(),
        ],
    },
    arguments = {
        Foo = [12i32],
    },

    // If there are multiple interface or service definitions, they are
    // merged together. This means we can have providers registered only in
    // certain environments.
    #[cfg(test)]
    interfaces = {
        dyn Fooable = [
            Quux.singleton(),
        ],
    },
};

let mut builder = Injector::builder();
builder.add_module(module);

let injector = builder.build();
let baz: Svc<Baz> = injector.get().unwrap();

#[cfg(not(test))]
assert_eq!(2, baz.0.len());
#[cfg(test)]
assert_eq!(3, baz.0.len());