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.
The cache is automatically invalidated whenever this container is
mutated (services registered, removed, or cleared), so calling this
manually is rarely necessary. It remains available for explicit
control, e.g. to release the cached Arcs held by the current thread.
Note: This clears the calling thread’s entire hot cache, including entries cached for other containers.
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 debug_registrations(&self) -> String
pub fn debug_registrations(&self) -> String
Format a human-readable summary of every registration visible to this container, for logging when a resolution unexpectedly fails.
The summary lists the scope depth, the number of services registered
in each scope of the parent chain, and the TypeId of every
registration. The container stores services by TypeId only (type
names are not retained), so pair this output with the type_name
carried by DiError::NotFound when diagnosing a failed resolve.
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct MyService;
let root = Container::new();
root.singleton(MyService);
let scope = root.scope();
if scope.get::<String>().is_err() {
eprintln!("{}", scope.debug_registrations());
}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 remove<T: Injectable>(&self) -> bool
pub fn remove<T: Injectable>(&self) -> bool
Remove a service registration from this scope.
Returns true if a service of type T was registered in this scope
and has been removed, false otherwise. Does not affect parent scopes.
Like clear, removal is permitted on a locked
container (locking prevents new registrations, not removal).
§Examples
use dependency_injector::Container;
#[derive(Clone)]
struct MyService;
let container = Container::new();
container.singleton(MyService);
assert!(container.remove::<MyService>());
assert!(!container.contains::<MyService>());
assert!(!container.remove::<MyService>()); // Already removedSourcepub 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>());