#dependency-injection #di #ioc

no-std froodi

An ergonomic Rust IoC container

15 releases

new 1.0.0-beta.13 Nov 3, 2025
1.0.0-beta.12 Oct 30, 2025
1.0.0-beta.6 Sep 18, 2025
1.0.0-beta.4 Aug 27, 2025

#177 in Development tools

Download history 62/week @ 2025-07-27 54/week @ 2025-08-03 1/week @ 2025-08-10 120/week @ 2025-08-17 213/week @ 2025-08-24 31/week @ 2025-08-31 3/week @ 2025-09-07 222/week @ 2025-09-14 36/week @ 2025-09-21 14/week @ 2025-09-28 8/week @ 2025-10-05 497/week @ 2025-10-12 43/week @ 2025-10-19 278/week @ 2025-10-26

827 downloads per month

Apache-2.0

295KB
6.5K SLoC

Froodi - an ergonomic Rust IoC container

Crates.io

Froodi is a lightweight, ergonomic Inversion of Control (IoC) container for Rust that helps manage dependencies with clear scoping and lifecycle management in a simple manner

Features

  • Scoping: Any object can have a lifespan for the entire app, a single request, or even more fractionally
  • Finalization: Some dependencies, like database connections, need not only to be created but also carefully released. Many frameworks lack this essential feature.
  • Ergonomic: Simple API
  • Speed: Dependency resolving as fast as the speed of light thanks to the Rust
  • Integration: The popular frameworks for building applications is supported out of the box (axum, dptree)
  • Safe: 100% safe Rust (no unsafe used)
  • Thread safe: Thread safety enabled by default (thread_safe feature) and can be disabled to use Rc instead of Arc and off Send/Sync requirements

Community

Telegram

Quickstart

use froodi::{
    Container,
    DefaultScope::{App, Request},
    Inject, InjectTransient, InstantiatorResult, instance, registry,
};

#[derive(Default, Clone)]
struct Config {
    _host: &'static str,
    _port: i16,
    _user: &'static str,
    _password: &'static str,
    _db: &'static str,
}

trait UserRepo {
    fn create_user(&self);
}

struct PostgresUserRepo;

impl UserRepo for PostgresUserRepo {
    fn create_user(&self) {
        todo!()
    }
}

struct CreateUser<R> {
    repo: R,
}

impl<R: UserRepo> CreateUser<R> {
    fn handle(&self) {
        self.repo.create_user();
    }
}

fn init_container(config: Config) -> Container {
    #[allow(clippy::unnecessary_wraps)]
    fn create_user<R>(InjectTransient(repo): InjectTransient<R>) -> InstantiatorResult<CreateUser<R>> {
        Ok(CreateUser { repo })
    }

    Container::new(registry! {
        provide(App, instance(config)),
        scope(Request) [
            provide(|_config: Inject<Config>| Ok(PostgresUserRepo)),
            provide(create_user::<PostgresUserRepo>),
        ],
    })
}

fn main() {
    let app_container = init_container(Config::default());
    let request_container = app_container.clone().enter_build().unwrap();

    let interactor = request_container.get_transient::<CreateUser<PostgresUserRepo>>().unwrap();
    interactor.handle();

    let _config = request_container.get::<Config>().unwrap();

    request_container.close();
    app_container.close();
}

Examples

  • Sync provide. This example shows how to provide sync dependencies.
  • Async provide. This example shows how to provide async sync dependencies.
  • Sync finalizer. This example shows how to add sync finalizers.
  • Async finalizer. This example shows how to add async finalizers.
  • Boxed dyn provide. This example shows how to provide boxed dyn dependencies.
  • Axum. This example shows how to integrate the framework with Axum library.
  • Dptree. This example shows how to integrate the framework with Dptree library.
  • Telers. This example shows how to integrate the framework with Telers framework.

You may consider checking out this directory for examples.

Contributing

Contributions are welcome!

License

Apache License, Version 2.0

Dependencies

~1–17MB
~181K SLoC