Crate hypospray [] [src]

Dependency Injection (DI)

Goals

  • Focused, reusable, testable components
  • A dependency graph checked at compile time

What is Dependency Injection?

5-minute introduction.

Cyclic Dependency

DI is not for circular dependency resolution: Circular dependency is something that is to be avoided.

Example

#![feature(plugin)]
#![plugin(hypospray_extensions)]
extern crate hypospray;

use hypospray::{Co, Construct, Graph};

trait Engine {

    fn rev(&self) -> &'static str;
}

#[implements(Engine)]
struct GranCabrioV8;

impl Engine for GranCabrioV8 {

    fn rev(&self) -> &'static str {

        return "Vrooom! Vroom! Vroooom!!!";
    }
}

impl<'dep> Construct<'dep> for GranCabrioV8 {

    type Dep = ();

    fn __construct(_: Self::Dep) -> GranCabrioV8 {
        GranCabrioV8
    }
}

#[inject(Engine)]
trait Deps { }

struct SportsCar<M: ?Sized + Deps> { engine: Co<M, Engine> }

impl<M: ?Sized + Deps> SportsCar<M> {

    fn gas(&self) {

        println!("{}", self.engine.rev());
    }
}

impl<'dep, M> Construct<'dep> for SportsCar<M> where M: ?Sized + Deps {

    type Dep = Co<M, Engine>;

    fn __construct(engine: Self::Dep) -> SportsCar<M> {
        SportsCar {
            engine: engine,
        }
    }
}

#[bind(Engine = "GranCabrioV8#Prototype")]
trait Module { }

type ModuleDependencies = Graph<Module>;

let m = ModuleDependencies::new();

let car: SportsCar<_> = m.construct();

car.gas();

Structs

Co
Graph

Enums

Prototype
Singleton

Traits

Component
ComponentImp

Component implementation

Construct

Construct