Skip to main content

PooledScope

Struct PooledScope 

Source
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§

Source§

impl PooledScope<'_>

Source

pub fn container(&self) -> &Container

Get a reference to the underlying container.

Methods from Deref<Target = Container>§

Source

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>());
Source

pub fn create_scope(&self) -> Self

Alias for scope() - creates a child container.

Source

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() });
Source

pub fn lazy<T: Injectable, F>(&self, factory: F)
where F: Fn() -> T + Send + Sync + 'static,

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
});
Source

pub fn transient<T: Injectable, F>(&self, factory: F)
where F: Fn() -> T + Send + Sync + 'static,

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 instances
Source

pub fn register_factory<T: Injectable, F>(&self, factory: F)
where F: Fn() -> T + Send + Sync + 'static,

Register using a factory (alias for lazy).

Source

pub fn register<T: Injectable>(&self, instance: T)

Register an instance (alias for singleton).

Source

pub fn register_boxed<T: Injectable>(&self, instance: Box<T>)

Register a boxed instance.

Source

pub fn register_by_id( &self, type_id: TypeId, instance: Arc<dyn Any + Send + Sync>, )

Register by TypeId directly (advanced use).

Source

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();
Source

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.

Source

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>();
Source

pub fn resolve<T: Injectable>(&self) -> Result<Arc<T>>

Alias for get - resolve a service.

Source

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());
Source

pub fn try_resolve<T: Injectable>(&self) -> Option<Arc<T>>

Alias for try_get.

Source

pub fn contains<T: Injectable>(&self) -> bool

Check if a service is registered.

Checks both current scope and parent scopes.

Source

pub fn has<T: Injectable>(&self) -> bool

Alias for contains.

Source

pub fn len(&self) -> usize

Get the number of services in this scope (not including parents).

Source

pub fn is_empty(&self) -> bool

Check if this scope is empty.

Source

pub fn registered_types(&self) -> Vec<TypeId>

Get all registered TypeIds in this scope.

Source

pub fn depth(&self) -> u32

Get the scope depth (0 = root).

Source

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());
}
Source

pub fn lock(&self)

Lock the container to prevent further registrations.

Useful for ensuring no services are registered after app initialization.

Source

pub fn is_locked(&self) -> bool

Check if the container is locked.

Source

pub fn clear(&self)

Clear all services from this scope.

Does not affect parent scopes.

Source

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 removed
Source

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();
Source

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>());

Trait Implementations§

Source§

impl Deref for PooledScope<'_>

Source§

type Target = Container

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl Drop for PooledScope<'_>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for PooledScope<'a>

§

impl<'a> !UnwindSafe for PooledScope<'a>

§

impl<'a> Freeze for PooledScope<'a>

§

impl<'a> Send for PooledScope<'a>

§

impl<'a> Sync for PooledScope<'a>

§

impl<'a> Unpin for PooledScope<'a>

§

impl<'a> UnsafeUnpin for PooledScope<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<R, D> DepsPresent<D> for R

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Injectable for T
where T: Send + Sync + 'static,

Source§

fn type_id_of() -> TypeId
where Self: Sized,

Returns the TypeId of this type (for internal use)
Source§

fn type_name_of() -> &'static str
where Self: Sized,

Returns the type name for debugging
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Provider for T
where T: Injectable,

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<R, D> VerifyDeps<D> for R

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more