Skip to main content

Crate injectable_rs

Crate injectable_rs 

Source
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.
ContainerBuilder
Builder for constructing a Container.
DependencyGraph
A dependency graph of all injectable types in the application.
DynProvider
A dynamic, closure-based provider for types that cannot derive Injectable.
EmptySingletonStore
A minimal empty singleton store for containers with no singletons.
FactoryCtx
Scope-safe resolution context for factory closures.
GraphNode
A node in the dependency graph representing an injectable type.
Inject
A wrapper around Arc<T> that can be extracted from a ResolveContext.
ProviderRegistry
A registry of dynamically-registered providers for external types.
RequestScoped
One instance per request/task (reserved for future use).
ResolveContext
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§

GraphError
Errors that can occur during graph construction or validation.
InjectableError
Errors that can occur during dependency resolution.
ValidationError
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.
PostConstruct
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.
SingletonStore
Trait for generated typed singleton stores.

Type Aliases§

HookResult
A specialized result type for lifecycle hooks.
InjectableResult
A specialized Result type for injectable operations.

Attribute Macros§

injectable
Unified DI attribute macro.