How to Implement Dependency Injection in Rust

Implement Dependency Injection in Rust by defining traits and passing concrete implementations into structs via constructors.

Implement Dependency Injection in Rust by defining a trait for your dependency, creating a struct that holds an implementation of that trait, and passing the struct into functions or other structs that need it.

trait Database {
    fn query(&self, sql: &str) -> String;
}

struct RealDatabase;
impl Database for RealDatabase {
    fn query(&self, sql: &str) -> String {
        format!("Executing: {}", sql)
    }
}

struct Service {
    db: Box<dyn Database>,
}

impl Service {
    fn new(db: Box<dyn Database>) -> Self {
        Self { db }
    }

    fn run(&self) {
        let result = self.db.query("SELECT * FROM users");
        println!("{result}");
    }
}

fn main() {
    let db = Box::new(RealDatabase);
    let service = Service::new(db);
    service.run();
}