pub struct InjectionContext { /* private fields */ }di and non-WebAssembly only.Expand description
The main injection context for dependency resolution.
InjectionContext manages both request-scoped and singleton-scoped dependencies,
as well as dependency overrides for testing.
§Override Support
The context supports dependency overrides, which take precedence over normal dependency resolution. This is particularly useful for testing:
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
let singleton = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton).build();
// Set override for testing
ctx.dependency(create_database).override_with(Database::mock());Implementations§
Source§impl InjectionContext
impl InjectionContext
Sourcepub fn builder(
singleton_scope: impl Into<Arc<SingletonScope>>,
) -> InjectionContextBuilder
pub fn builder( singleton_scope: impl Into<Arc<SingletonScope>>, ) -> InjectionContextBuilder
Create a new InjectionContextBuilder.
This is the recommended way to construct an InjectionContext.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
let singleton_scope = SingletonScope::new();
let ctx = InjectionContext::builder(singleton_scope).build();Sourcepub fn get_http_request(&self) -> Option<&Request>
Available on crate feature params only.
pub fn get_http_request(&self) -> Option<&Request>
params only.Gets the HTTP request from the context.
Returns None if no request was set (e.g., when testing without HTTP context).
Returns a reference to the request.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope, Request, ParamContext};
let singleton_scope = SingletonScope::new();
let request = Request::builder()
.method(hyper::Method::GET)
.uri("/")
.build()
.unwrap();
let param_context = ParamContext::new();
let ctx = InjectionContext::builder(singleton_scope)
.with_request(request)
.with_param_context(param_context)
.build();
assert!(ctx.get_http_request().is_some());Sourcepub fn get_param_context(&self) -> Option<&ParamContext>
Available on crate feature params only.
pub fn get_param_context(&self) -> Option<&ParamContext>
params only.Gets the parameter context from the context.
Returns None if no parameter context was set.
Returns a reference to the parameter context.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope, Request, ParamContext};
let singleton_scope = SingletonScope::new();
let request = Request::builder()
.method(hyper::Method::GET)
.uri("/")
.build()
.unwrap();
let param_context = ParamContext::new();
let ctx = InjectionContext::builder(singleton_scope)
.with_request(request)
.with_param_context(param_context)
.build();
assert!(ctx.get_param_context().is_some());Sourcepub fn set_http_request(
&mut self,
request: Request,
param_context: ParamContext,
)
Available on crate feature params only.
pub fn set_http_request( &mut self, request: Request, param_context: ParamContext, )
params only.Sets the HTTP request and parameter context.
This can be used to add HTTP context to an existing InjectionContext. The request and parameter context will be wrapped in Arc internally.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope, Request, ParamContext};
let singleton_scope = SingletonScope::new();
let mut ctx = InjectionContext::builder(singleton_scope).build();
let request = Request::builder()
.method(hyper::Method::GET)
.uri("/")
.build()
.unwrap();
let param_context = ParamContext::new();
ctx.set_http_request(request, param_context);Sourcepub fn get_request<T>(&self) -> Option<Arc<T>>
pub fn get_request<T>(&self) -> Option<Arc<T>>
Retrieves a request-scoped value from the context.
Request-scoped values are cached only for the duration of a single request.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
let singleton_scope = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton_scope).build();
ctx.set_request(42i32);
let value = ctx.get_request::<i32>().unwrap();
assert_eq!(*value, 42);Sourcepub fn set_request<T>(&self, value: T)
pub fn set_request<T>(&self, value: T)
Stores a value in the request scope.
The value is cached for the duration of the current request only.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
let singleton_scope = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton_scope).build();
ctx.set_request("request-data".to_string());
assert!(ctx.get_request::<String>().is_some());Sourcepub fn get_singleton<T>(&self) -> Option<Arc<T>>
pub fn get_singleton<T>(&self) -> Option<Arc<T>>
Retrieves a singleton value from the context.
Singleton values persist across all requests and are shared application-wide.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
let singleton_scope = Arc::new(SingletonScope::new());
singleton_scope.set(100u64);
let ctx = InjectionContext::builder(singleton_scope).build();
let value = ctx.get_singleton::<u64>().unwrap();
assert_eq!(*value, 100);Sourcepub fn set_singleton<T>(&self, value: T)
pub fn set_singleton<T>(&self, value: T)
Stores a value in the singleton scope.
The value persists across all requests and is shared application-wide.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
let singleton_scope = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton_scope).build();
ctx.set_singleton("global-config".to_string());
assert!(ctx.get_singleton::<String>().is_some());Sourcepub fn singleton_scope(&self) -> &Arc<SingletonScope>
pub fn singleton_scope(&self) -> &Arc<SingletonScope>
Returns a reference to the singleton scope.
This is useful for advanced scenarios where direct access to the singleton scope is needed.
Sourcepub fn fork_for_request(&self, request: Request) -> InjectionContext
pub fn fork_for_request(&self, request: Request) -> InjectionContext
Creates a per-request fork of this context with an HTTP request.
The forked context shares the same singleton scope but has a fresh
request scope. When the params feature is enabled, the HTTP request
and its path parameters are made available for parameter extraction.
The HTTP request is stored in both the dedicated request field
(for get_http_request()) and the
request_scope (for get_request::<HttpRequest>()),
ensuring that Injectable types such as ServerFnRequest can
retrieve it via either accessor.
Sourcepub fn fork(&self) -> InjectionContext
pub fn fork(&self) -> InjectionContext
Creates a per-request fork of this context without an HTTP request.
The forked context shares the same singleton scope but has a fresh
request scope. Unlike fork_for_request, this method does not store
an HTTP request, so path parameter extraction is not available.
This is intended for non-HTTP protocols (gRPC, GraphQL) where request-scoped isolation is needed but HTTP request data is not available.
Sourcepub fn overrides(&self) -> &OverrideRegistry
pub fn overrides(&self) -> &OverrideRegistry
Returns a reference to the override registry.
The override registry stores function-level overrides that take precedence over normal dependency resolution.
Sourcepub fn dependency<O>(&self, func: fn() -> O) -> FunctionHandle<'_, O>
pub fn dependency<O>(&self, func: fn() -> O) -> FunctionHandle<'_, O>
Creates a handle for the given injectable function.
This method provides a fluent API for setting and managing dependency overrides. The function pointer is used as a unique key to identify which injectable function should be overridden.
§Note
This method is designed to work with functions annotated with #[injectable].
The #[injectable] macro generates a 0-argument function regardless of
the original function’s parameter count, as all #[inject] parameters
are resolved internally by the DI system.
§Type Parameters
O- The output type of the function (the dependency type)
§Arguments
func- A function pointer to the injectable function
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
let singleton = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton).build();
// Set override - create_database is 0-argument after macro expansion
ctx.dependency(create_database).override_with(Database::mock());
// Check if override exists
assert!(ctx.dependency(create_database).has_override());
// Clear override
ctx.dependency(create_database).clear_override();Sourcepub fn get_override<O>(&self, func_ptr: usize) -> Option<O>where
O: Clone + 'static,
pub fn get_override<O>(&self, func_ptr: usize) -> Option<O>where
O: Clone + 'static,
Sourcepub fn clear_overrides(&self)
pub fn clear_overrides(&self)
Clears all overrides from the context.
This is useful for cleanup in tests to ensure a clean state.
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
fn my_factory() -> i32 { 42 }
let singleton = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton).build();
ctx.dependency(my_factory).override_with(100);
assert!(ctx.dependency(my_factory).has_override());
ctx.clear_overrides();
assert!(!ctx.dependency(my_factory).has_override());Sourcepub async fn resolve<T>(&self) -> Result<Arc<T>, DiError>
pub async fn resolve<T>(&self) -> Result<Arc<T>, DiError>
Resolve a dependency from the global registry
This method implements the core dependency resolution logic:
- Check cache based on scope (Request or Singleton)
- If not cached, create using the factory from the global registry
- Cache the result according to the scope
§Examples
use reinhardt_di::{InjectionContext, SingletonScope};
use std::sync::Arc;
let singleton_scope = Arc::new(SingletonScope::new());
let ctx = InjectionContext::builder(singleton_scope).build();
let config = ctx.resolve::<Config>().await?;Trait Implementations§
Source§impl Clone for InjectionContext
impl Clone for InjectionContext
Source§fn clone(&self) -> InjectionContext
fn clone(&self) -> InjectionContext
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for InjectionContext
impl !RefUnwindSafe for InjectionContext
impl Send for InjectionContext
impl Sync for InjectionContext
impl Unpin for InjectionContext
impl UnsafeUnpin for InjectionContext
impl !UnwindSafe for InjectionContext
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
type Err = Infallible
fn into_result(self) -> Result<T, <T as IntoResult<T>>::Err>
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.