dependency-injector
A high-performance, lock-free dependency injection container for Rust.
Features
- 🚀 Lock-Free Performance - Built on
DashMapfor concurrent access without mutex contention - 🔒 Thread-Safe - Safe to use across threads with
Arc<Container> - 🎯 Type-Safe - Compile-time guarantees with Rust's type system
- 📦 Multiple Lifetimes - Singleton, transient, and lazy initialization
- 🌳 Scoped Containers - Create child containers with inherited and overridden services
- âš¡ Zero Config - No macros required, just plain Rust
Installation
Add to your Cargo.toml:
[]
= "0.1"
Optional Features
[]
= { = "0.1", = ["async", "tracing"] }
| Feature | Description |
|---|---|
tracing |
Integration with the tracing crate (enabled by default) |
async |
Async support with Tokio |
Quick Start
use Container;
// Define your services
Service Lifetimes
Singleton
Created immediately and shared across all resolutions:
container.singleton;
let config1 = container..unwrap;
let config2 = container..unwrap;
// config1 and config2 point to the same instance
Lazy Singleton
Created on first access, then shared:
container.lazy;
// Service is created here on first call
let svc = container..unwrap;
Transient
New instance created on every resolution:
container.transient;
let id1 = container..unwrap;
let id2 = container..unwrap;
// id1 and id2 are different instances
Scoped Containers
Create child containers that inherit from their parent:
// Root container with shared services
let root = new;
root.singleton;
// Per-request scope
let request_scope = root.scope;
request_scope.singleton;
// Child can access parent services
assert!;
assert!;
// Parent cannot access child services
assert!;
Service Overrides
Override parent services in child scopes:
let root = new;
root.singleton;
let test_scope = root.scope;
test_scope.singleton;
// Root still has production
let root_db = root..unwrap;
assert_eq!;
// Test scope has override
let test_db = test_scope..unwrap;
assert_eq!;
Framework Integration
With Armature
Armature is a Rust HTTP framework with built-in DI support:
use *;
use Container;
async
API Reference
| Method | Description |
|---|---|
Container::new() |
Create a new container |
singleton(service) |
Register an immediate singleton |
lazy(factory) |
Register a lazy-initialized singleton |
transient(factory) |
Register a transient service |
get::<T>() |
Resolve a service by type |
contains::<T>() |
Check if a service is registered |
remove::<T>() |
Remove a service registration |
scope() |
Create a child container |
Documentation
- 📚 Full Documentation - Comprehensive guides and API reference
- 📖 docs.rs - API documentation
- 📊 Benchmarks - Performance metrics
Performance
The container is built for high-performance scenarios:
- Lock-free reads using
DashMap - Minimal allocations with
Arcsharing - No runtime reflection - all type resolution at compile time
Run benchmarks locally:
Contributing
Contributions are welcome! Please read our Contributing Guide before submitting a PR.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Acknowledgments
Inspired by dependency injection patterns from:
- Angular - Hierarchical injectors
- NestJS - Module-based DI
- Microsoft.Extensions.DependencyInjection - Service lifetimes