pub struct PooledScope<'a> { /* private fields */ }Expand description
A scope acquired from a pool that automatically returns when dropped.
This provides RAII-style management of pooled scopes, ensuring they’re always returned to the pool even if the code panics.
Implementations§
Methods from Deref<Target = Container>§
Sourcepub fn scope(&self) -> Self
pub fn scope(&self) -> Self
Create a child scope that inherits from this container.
Child scopes can:
- Access all services from parent scopes
- Override parent services with local registrations
- Have their own transient/scoped services
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct AppConfig { debug: bool }
#[derive(Clone)]
struct RequestId(String);
let root = Container::new();
root.singleton(AppConfig { debug: true });
let request = root.scope();
request.singleton(RequestId("req-123".into()));
// Request scope can access root config
assert!(request.contains::<AppConfig>());Sourcepub fn create_scope(&self) -> Self
pub fn create_scope(&self) -> Self
Alias for scope() - creates a child container.
Sourcepub fn singleton<T: Injectable>(&self, instance: T)
pub fn singleton<T: Injectable>(&self, instance: T)
Register a singleton service (eager).
The instance is stored immediately and shared across all resolves.
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct Database { url: String }
let container = Container::new();
container.singleton(Database { url: "postgres://localhost".into() });Sourcepub fn lazy<T: Injectable, F>(&self, factory: F)
pub fn lazy<T: Injectable, F>(&self, factory: F)
Register a lazy singleton service.
The factory is called once on first access, then the instance is cached.
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct ExpensiveService { data: Vec<u8> }
let container = Container::new();
container.lazy(|| ExpensiveService {
data: vec![0; 1024 * 1024], // Only allocated on first use
});Sourcepub fn transient<T: Injectable, F>(&self, factory: F)
pub fn transient<T: Injectable, F>(&self, factory: F)
Register a transient service.
A new instance is created on every resolve.
§Examples
use dependency_injector::Container;
use std::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(0);
#[derive(Clone)]
struct RequestId(u64);
let container = Container::new();
container.transient(|| RequestId(COUNTER.fetch_add(1, Ordering::SeqCst)));
let id1 = container.get::<RequestId>().unwrap();
let id2 = container.get::<RequestId>().unwrap();
assert_ne!(id1.0, id2.0); // Different instancesSourcepub fn register_factory<T: Injectable, F>(&self, factory: F)
pub fn register_factory<T: Injectable, F>(&self, factory: F)
Register using a factory (alias for lazy).
Sourcepub fn register<T: Injectable>(&self, instance: T)
pub fn register<T: Injectable>(&self, instance: T)
Register an instance (alias for singleton).
Sourcepub fn register_boxed<T: Injectable>(&self, instance: Box<T>)
pub fn register_boxed<T: Injectable>(&self, instance: Box<T>)
Register a boxed instance.
Sourcepub fn register_by_id(
&self,
type_id: TypeId,
instance: Arc<dyn Any + Send + Sync>,
)
pub fn register_by_id( &self, type_id: TypeId, instance: Arc<dyn Any + Send + Sync>, )
Register by TypeId directly (advanced use).
Sourcepub fn get<T: Injectable>(&self) -> Result<Arc<T>>
pub fn get<T: Injectable>(&self) -> Result<Arc<T>>
Resolve a service by type.
Returns Arc<T> for zero-copy sharing. Walks the parent chain if
not found in the current scope.
§Performance
Uses thread-local caching for frequently accessed services (~8ns vs ~19ns). The cache is automatically populated on first access.
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct MyService;
let container = Container::new();
container.singleton(MyService);
let service = container.get::<MyService>().unwrap();Sourcepub fn clear_cache(&self)
pub fn clear_cache(&self)
Clear the thread-local hot cache.
Call this after modifying the container (registering/removing services) if you want subsequent resolutions to see the changes immediately.
Note: The cache is automatically invalidated when services are re-registered, but this method can be used for explicit control.
Sourcepub fn warm_cache<T: Injectable>(&self)
pub fn warm_cache<T: Injectable>(&self)
Pre-warm the thread-local cache with a specific service type.
This can be useful at the start of request handling to ensure hot services are already in the cache.
§Example
use dependency_injector::Container;
#[derive(Clone)]
struct Database;
let container = Container::new();
container.singleton(Database);
// Pre-warm cache for hot services
container.warm_cache::<Database>();Sourcepub fn resolve<T: Injectable>(&self) -> Result<Arc<T>>
pub fn resolve<T: Injectable>(&self) -> Result<Arc<T>>
Alias for get - resolve a service.
Sourcepub fn try_get<T: Injectable>(&self) -> Option<Arc<T>>
pub fn try_get<T: Injectable>(&self) -> Option<Arc<T>>
Try to resolve, returning None if not found.
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct OptionalService;
let container = Container::new();
assert!(container.try_get::<OptionalService>().is_none());Sourcepub fn try_resolve<T: Injectable>(&self) -> Option<Arc<T>>
pub fn try_resolve<T: Injectable>(&self) -> Option<Arc<T>>
Alias for try_get.
Sourcepub fn contains<T: Injectable>(&self) -> bool
pub fn contains<T: Injectable>(&self) -> bool
Check if a service is registered.
Checks both current scope and parent scopes.
Sourcepub fn has<T: Injectable>(&self) -> bool
pub fn has<T: Injectable>(&self) -> bool
Alias for contains.
Sourcepub fn registered_types(&self) -> Vec<TypeId>
pub fn registered_types(&self) -> Vec<TypeId>
Get all registered TypeIds in this scope.
Sourcepub fn lock(&self)
pub fn lock(&self)
Lock the container to prevent further registrations.
Useful for ensuring no services are registered after app initialization.
Sourcepub fn batch<F>(&self, f: F)where
F: FnOnce(BatchRegistrar<'_>),
pub fn batch<F>(&self, f: F)where
F: FnOnce(BatchRegistrar<'_>),
Register multiple services in a single batch operation.
This is more efficient than individual registrations when registering many services at once, as it:
- Performs a single lock check at the start
- Minimizes per-call overhead
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct Database { url: String }
#[derive(Clone)]
struct Cache { size: usize }
#[derive(Clone)]
struct Logger { level: String }
let container = Container::new();
container.batch(|batch| {
batch.singleton(Database { url: "postgres://localhost".into() });
batch.singleton(Cache { size: 1024 });
batch.singleton(Logger { level: "info".into() });
});
assert!(container.contains::<Database>());
assert!(container.contains::<Cache>());
assert!(container.contains::<Logger>());Note: For maximum performance with many services, prefer the builder API:
use dependency_injector::Container;
#[derive(Clone)]
struct A;
#[derive(Clone)]
struct B;
let container = Container::new();
container.register_batch()
.singleton(A)
.singleton(B)
.done();Sourcepub fn register_batch(&self) -> BatchBuilder<'_>
pub fn register_batch(&self) -> BatchBuilder<'_>
Start a fluent batch registration.
This is faster than the closure-based batch() for many services
because it avoids closure overhead.
§Example
use dependency_injector::Container;
#[derive(Clone)]
struct Database { url: String }
#[derive(Clone)]
struct Cache { size: usize }
let container = Container::new();
container.register_batch()
.singleton(Database { url: "postgres://localhost".into() })
.singleton(Cache { size: 1024 })
.done();
assert!(container.contains::<Database>());
assert!(container.contains::<Cache>());