Compile-time dependency injector for Rust inspired by Dagger 2
std::sync::Arc
Clone
Clone
```rust use std::rc::Rc;
// define your business logic
/// printer trait pub trait Printer { fn print(&self, input: &str); }
/// a printer implementation pub struct StdoutPrinter;
impl Printer for StdoutPrinter { fn print(&self, input: &str) { println!("{}", input); } }
/// greeter for messages
pub struct Greeter {
message: String,
printer: Rc
impl Greeter {
/// constructor with dependencies
pub fn new(message: String, printer: Rc
/// your business logic
pub fn say_hello(&self) {
self.printer.print(&self.message);
}
}
/// module that is parsed to create the dependency injection /// code
mod integration { use super::*;
pub struct DemoModule;
/// use strong types when in need to distinguish
pub struct Message(String);
/// Define how to create your dependencies
impl DemoModule {
#[singleton]
pub fn provide_printer() -> Rc<dyn Printer> {
Rc::new(StdoutPrinter)
}
pub fn provide_message() -> Message {
Message("Hello World".to_string())
}
pub fn provide_greeter(
message: Message,
printer: Rc<dyn Printer>
) -> Greeter {
Greeter::new(message.0, printer)
}
}
/// Define which dependencies you need.
///
/// A struct `DemoComponentImpl` will be created for
/// you which implements `DemoComponent`.
pub trait DemoComponent {
/// request the to create injection code for
/// our main class `Greeter`
fn resolve_greeter(&self) -> Greeter;
}
}
fn main() { // import component trait use crate::integration::DemoComponent;
// use generated component implementation
let injector = integration::DemoComponentImpl::new();
// Resolve main dependency
// Note: it can not fail at runtime!
let greeter = injector.resolve_greeter();
// enjoy!
greeter.say_hello();
} ```
Result
in module)