Expand description
§injectable — Compile-time Dependency Injection for Rust
A compile-time dependency injection framework using extractor-based DI,
inspired by Axum’s typed extraction model. No TypeId in the public
API, no runtime reflection, no HashMap<TypeId, Box<dyn Any>>.
§Core Philosophy
Dependencies are resolved through typed extractors, not dynamic lookup. Provider chains are generated at compile time. Constructor parameters behave like Axum extractors. Dependency traversal is statically encoded into generated provider implementations.
§Types You Own vs. Types You Don’t
§Types You Own — #[injectable]
For types in your own crate, use the derive macro:
ⓘ
use injectable_rs::{Injectable, Inject, Container};
#[injectable]
#[derive(Default)]
pub struct Database { pool_size: usize }
#[injectable]
#[derive(Default)]
pub struct UserService { db: Arc<Database> }§Types You Don’t Own — DynProvider
For types from third-party crates (reqwest::Client, sqlx::SqlitePool,
etc.), you can’t add #[injectable]. Instead, register a
dynamic provider:
ⓘ
use injectable_rs::{Container, DynProvider};
let container = Container::builder()
.register("", DynProvider::new(|| {
Ok(reqwest::Client::new())
}))
.register("", DynProvider::with_ctx(|ctx| async move {
let config = ctx.resolve::<AppConfig>().await?;
Ok(sqlx::SqlitePool::connect(&config.db_url).await?)
}))
.build()
.await?;
// Resolve owned types (static path)
let service = container.resolve::<UserService>().await?;
// Resolve external types (registry path)
let client = container.resolve_external::<reqwest::Client>().await?;Modules§
- prelude
- Commonly used items —
use injectable_rs::prelude::*covers the full public API.
Macros§
- bind
- Macro to create a static binding from a trait to a concrete type.
- container
- Macro for compile-time dependency graph validation and container construction.
Structs§
- Container
- The dependency injection container.
- Container
Builder - Builder for constructing a
Container. - Dependency
Graph - A dependency graph of all injectable types in the application.
- DynProvider
- A dynamic, closure-based provider for types that cannot derive
Injectable. - Empty
Singleton Store - A minimal empty singleton store for containers with no singletons.
- Factory
Ctx - Scope-safe resolution context for factory closures.
- Graph
Node - A node in the dependency graph representing an injectable type.
- Inject
- A wrapper around
Arc<T>that can be extracted from aResolveContext. - Provider
Registry - A registry of dynamically-registered providers for external types.
- Request
Scoped - One instance per request/task (reserved for future use).
- Resolve
Context - The resolution context passed through provider chains.
- Singleton
- One instance per container (the default scope).
- Transient
- A fresh instance is created on every resolution.
Enums§
- Graph
Error - Errors that can occur during graph construction or validation.
- Injectable
Error - Errors that can occur during dependency resolution.
- Validation
Error - Errors found during dependency graph validation.
Constants§
- DEFAULT_
TOKEN - The default (unnamed) provider token.
Traits§
- Extract
- Axum-inspired extractor trait for dependency resolution.
- Injectable
- The primary trait for types that can be dependency-injected.
- Post
Construct - Trait for post-construction lifecycle hooks.
- PreDestruct
- Trait for pre-destruction lifecycle hooks.
- Provider
- A provider that can asynchronously construct a value of type
T. - Singleton
Store - Trait for generated typed singleton stores.
Type Aliases§
- Hook
Result - A specialized result type for lifecycle hooks.
- Injectable
Result - A specialized
Resulttype for injectable operations.
Attribute Macros§
- injectable
- Unified DI attribute macro.