pub struct ServiceProvider { /* private fields */ }Implementations§
Source§impl ServiceProvider
impl ServiceProvider
Sourcepub fn register_disposable(&self, cleanup: Box<dyn FnOnce() + Send>)
pub fn register_disposable(&self, cleanup: Box<dyn FnOnce() + Send>)
Register a cleanup closure for scoped services/owned resources.
Closures run (in reverse registration order) when
Self::dispose is called — either explicitly or by Scope’s
Drop for scope providers.
Sourcepub fn dispose(&self)
pub fn dispose(&self)
Dispose this provider: release cached instances in reverse creation order, run registered cleanups in reverse registration order, and mark the provider unusable.
- Root provider: also marks the whole provider tree disposed (existing scopes can no longer resolve), drains the singleton cache, and clears named registrations. Singleton instances are released in reverse creation order (LIFO), so dependents drop before their dependencies.
- Scope provider: releases the scoped instances created in that scope and runs its cleanups. Singletons are untouched.
Idempotent. Instances are released by dropping the container’s strong
references; a service’s Drop runs when no other owner keeps it alive.
Services obtained via get_owned are caller-owned and are not tracked.
The caller must not resolve services concurrently with disposal (same
contract as MEDI’s ServiceProvider.Dispose). A panicking cleanup closure
does not stop the remaining cleanups; the first panic is re-raised after
disposal (and swallowed when the thread is already unwinding, e.g. during
Scope’s Drop).
Sourcepub fn get<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, RdiError>
pub fn get<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, RdiError>
Resolve a service by type. Works uniformly for concrete types and trait objects.
Returns Err(RdiError::ServiceNotFound) if not registered.
ScopeFactory is always available from a built provider (no manual
registration required). An explicit singleton::<dyn ScopeFactory>(...)
registration still takes precedence. Later registrations override earlier
ones (MEDI semantics).
Sourcepub fn get_optional<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>>
pub fn get_optional<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>>
Resolve a service by type, returning None if it is not registered or
not resolvable at this point (e.g. a scoped service under root scope
validation, or a disposed provider). Use Self::get when you need the
concrete error.
Sourcepub fn get_async<T: ?Sized + Send + Sync + 'static>(
&self,
) -> impl Future<Output = Result<Arc<T>, RdiError>> + Send + '_
pub fn get_async<T: ?Sized + Send + Sync + 'static>( &self, ) -> impl Future<Output = Result<Arc<T>, RdiError>> + Send + '_
Resolve an async service by type.
The returned future captures the current async resolution chain at
construction time (synchronously), so nested resolution inherits the
chain even when the future is moved to another task. For fully detached
task closures, propagate Self::async_context (see its docs).
Sourcepub fn get_keyed_async<T: ?Sized + Send + Sync + 'static>(
&self,
key: impl Into<ServiceKey> + Send,
) -> impl Future<Output = Result<Arc<T>, RdiError>> + Send + '_
pub fn get_keyed_async<T: ?Sized + Send + Sync + 'static>( &self, key: impl Into<ServiceKey> + Send, ) -> impl Future<Output = Result<Arc<T>, RdiError>> + Send + '_
Resolve an async keyed service by type and key.
Accepts string keys and typed ServiceKey values. AnyKey fallback
registrations are synchronous by design and are resolved through the
synchronous keyed path.
Sourcepub fn get_keyed<T: ?Sized + Send + Sync + 'static>(
&self,
key: impl Into<ServiceKey>,
) -> Result<Arc<T>, RdiError>
pub fn get_keyed<T: ?Sized + Send + Sync + 'static>( &self, key: impl Into<ServiceKey>, ) -> Result<Arc<T>, RdiError>
Resolve a keyed service by type and key. Resolve a keyed service by type and key.
Accepts string keys ("name") as well as typed ServiceKey values.
Exact-key registrations take precedence; otherwise an AnyKey fallback
registration is used for the requested key.
Returns Err(RdiError::KeyedServiceNotFound) if not found.
Sourcepub fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError>
pub fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError>
Resolve owned T (bypass cache, fresh each call).
Returns Err if not registered or the service is Singleton.
Owned resolution hands the instance to the caller: it is not tracked by
the container and stays valid after dispose. Scoped ownership bypasses
the scope cache, so a root scope-validation error is not raised for the
owned instance itself; its dependencies still obey scope validation.
Sourcepub fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T>
pub fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T>
Resolve owned T, returning None if not registered, a Singleton, or the
provider/scope is disposed.
Sourcepub fn get_keyed_owned<T: Send + Sync + 'static>(
&self,
key: impl Into<ServiceKey>,
) -> Result<T, RdiError>
pub fn get_keyed_owned<T: Send + Sync + 'static>( &self, key: impl Into<ServiceKey>, ) -> Result<T, RdiError>
Resolve owned keyed T.
Returns Err if not found or Singleton.
Sourcepub fn try_get_keyed_owned<T: Send + Sync + 'static>(
&self,
key: impl Into<ServiceKey>,
) -> Option<T>
pub fn try_get_keyed_owned<T: Send + Sync + 'static>( &self, key: impl Into<ServiceKey>, ) -> Option<T>
Resolve owned keyed T, returning None if not found, a Singleton, or
the provider/scope is disposed.
Sourcepub fn get_all<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>>
pub fn get_all<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>>
Return all unkeyed registered instances of the given type, in
registration order (MEDI GetServices<T>() / IEnumerable<T> parity).
Keyed implementations are excluded — use Self::get_all_keyed for
those. Under root scope validation, scoped services are not resolvable at
the root and are omitted; other resolution failures panic with a typed
RdiError payload (mirroring MEDI, where enumeration throws).
Sourcepub fn get_all_keyed<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>>
pub fn get_all_keyed<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>>
Return all keyed registered instances of the given type, in
registration order (MEDI GetKeyedServices<T>(KeyedService.AnyKey) parity).
AnyKey fallback registrations are excluded: MEDI’s AnyKey enumeration
returns only registrations with an explicit key.
Sourcepub fn scope(self: &Arc<Self>) -> Scope
pub fn scope(self: &Arc<Self>) -> Scope
Create a new service scope.
Analogous to IServiceProvider.CreateScope() in MEDI.
Scoped-lifetime services are cached within the returned scope.
Sourcepub fn is_registered<T: ?Sized + Send + Sync + 'static>(&self) -> bool
pub fn is_registered<T: ?Sized + Send + Sync + 'static>(&self) -> bool
Whether T has a resolvable registration (or is a built-in container
service). MEDI IServiceProviderIsService parity.
Reports registration state only: it is still true after Self::dispose.
Sourcepub fn is_registered_keyed<T: ?Sized + Send + Sync + 'static>(
&self,
key: impl Into<ServiceKey>,
) -> bool
pub fn is_registered_keyed<T: ?Sized + Send + Sync + 'static>( &self, key: impl Into<ServiceKey>, ) -> bool
Whether T has a registration under key (exact key, or an AnyKey
fallback registration). MEDI IServiceProviderIsService.IsKeyedService parity.
Sourcepub fn get_named<T: Send + Sync + 'static>(&self, name: &str) -> Option<Arc<T>>
pub fn get_named<T: Send + Sync + 'static>(&self, name: &str) -> Option<Arc<T>>
Cross-DLL safe named service resolution (generic).
Sourcepub fn get_named_any(&self, name: &str) -> Option<Arc<dyn Any + Send + Sync>>
pub fn get_named_any(&self, name: &str) -> Option<Arc<dyn Any + Send + Sync>>
Non-generic named resolution; returns Arc<dyn Any> for trait-object dispatch.
Sourcepub fn register_named<T: Send + Sync + 'static>(
&self,
name: &str,
service: Arc<T>,
)
pub fn register_named<T: Send + Sync + 'static>( &self, name: &str, service: Arc<T>, )
Register a named service for cross-DLL plugin access.
No-op after the provider/scope has been disposed (the named registry is
cleared by Self::dispose).
Sourcepub fn remove_named(&self, name: &str)
pub fn remove_named(&self, name: &str)
Remove a named service (for plugin unload).
Sourcepub fn rdi_register_named(
&self,
name: &str,
service: Arc<dyn Any + Send + Sync>,
)
pub fn rdi_register_named( &self, name: &str, service: Arc<dyn Any + Send + Sync>, )
Register a named service (for IProvider trait).
No-op after the provider/scope has been disposed.
Sourcepub fn rdi_remove_named(&self, name: &str)
pub fn rdi_remove_named(&self, name: &str)
Remove a named service (for IProvider trait).
Source§impl ServiceProvider
impl ServiceProvider
Sourcepub fn async_context(&self) -> Option<AsyncFactoryContext>
pub fn async_context(&self) -> Option<AsyncFactoryContext>
Create an AsyncFactoryContext bound to the current async
resolution chain.
Call this inside an async factory (before spawning) to get a handle that
can be cloned into detached tasks. Outside a factory the context starts a
fresh chain. Returns None only for a provider whose self-reference is
not initialized (should not happen for a built provider).
Trait Implementations§
Source§impl IProvider for ServiceProvider
impl IProvider for ServiceProvider
Source§impl IServiceResolver for ServiceProvider
impl IServiceResolver for ServiceProvider
Source§fn try_get_any_result(
&self,
key: &str,
) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
fn try_get_any_result( &self, key: &str, ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
Infallible lookup: reports absence instead of panicking for scope
violations / disposal (still returns Err for factory failures so
callers could distinguish, but IServiceResolver::try_get maps it to
None).
Source§fn try_get_keyed_any_result(
&self,
key: &str,
variant: &str,
) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
fn try_get_keyed_any_result( &self, key: &str, variant: &str, ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
Keyed variant of IServiceResolver::try_get_any_result.
fn get_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>>
fn get_keyed_any( &self, key: &str, variant: &str, ) -> Option<Arc<dyn Any + Send + Sync>>
Source§fn get_keyed_any_key(
&self,
key: &str,
variant: &ServiceKey,
) -> Option<Arc<dyn Any + Send + Sync>>
fn get_keyed_any_key( &self, key: &str, variant: &ServiceKey, ) -> Option<Arc<dyn Any + Send + Sync>>
#[inject(key = <expr>)]). Read moreSource§fn try_get_keyed_any_result_key(
&self,
key: &str,
variant: &ServiceKey,
) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
fn try_get_keyed_any_result_key( &self, key: &str, variant: &ServiceKey, ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
Self::get_keyed_any_key.Source§fn get_keyed_owned_any_key(
&self,
key: &str,
variant: &ServiceKey,
) -> Option<Arc<dyn Any + Send + Sync>>
fn get_keyed_owned_any_key( &self, key: &str, variant: &ServiceKey, ) -> Option<Arc<dyn Any + Send + Sync>>
Source§fn try_get_keyed_owned_any_key(
&self,
key: &str,
variant: &ServiceKey,
) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
fn try_get_keyed_owned_any_key( &self, key: &str, variant: &ServiceKey, ) -> Result<Option<Arc<dyn Any + Send + Sync>>, RdiError>
Self::get_keyed_owned_any_key.Source§fn get_keyed_by_type_id(
&self,
tid: TypeId,
key: &str,
) -> Option<Arc<dyn Any + Send + Sync>>
fn get_keyed_by_type_id( &self, tid: TypeId, key: &str, ) -> Option<Arc<dyn Any + Send + Sync>>
None)。 Read moreSource§fn get_all_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>>
fn get_all_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>>
Source§fn get_all_keyed_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>>
fn get_all_keyed_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>>
GetKeyedServices<T>(KeyedService.AnyKey)). Read moreSource§fn get_all_any_result(
&self,
key: &str,
) -> Result<Vec<Arc<dyn Any + Send + Sync>>, RdiError>
fn get_all_any_result( &self, key: &str, ) -> Result<Vec<Arc<dyn Any + Send + Sync>>, RdiError>
Self::get_all_any, used by the inject
macros for Vec<Arc<T>> fields. Read moreSource§fn get_owned_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>>
fn get_owned_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>>
Arc<dyn Any + Send + Sync> (concrete Arc<Arc<T>>). Read morefn get_keyed_owned_any( &self, key: &str, variant: &str, ) -> Option<Arc<dyn Any + Send + Sync>>
Source§fn provider_arc(&self) -> Option<Arc<ServiceProvider>>
fn provider_arc(&self) -> Option<Arc<ServiceProvider>>
Arc<ServiceProvider> for on-demand service resolution. Read moreSource§fn get<T: ?Sized + Sync + Send + 'static>(&self) -> Result<Arc<T>, RdiError>where
Self: Sized,
fn get<T: ?Sized + Sync + Send + 'static>(&self) -> Result<Arc<T>, RdiError>where
Self: Sized,
dyn Trait).
Returns Err(RdiError::ServiceNotFound) if not registered. Read moreSource§fn try_get<T: ?Sized + Sync + Send + 'static>(&self) -> Option<Arc<T>>where
Self: Sized,
fn try_get<T: ?Sized + Sync + Send + 'static>(&self) -> Option<Arc<T>>where
Self: Sized,
None if it is not registered or
not resolvable at this point (e.g. a scoped service under root scope
validation, or a disposed provider/scope). Read moreSource§fn get_keyed<T: ?Sized + Sync + Send + 'static>(
&self,
variant: &str,
) -> Result<Arc<T>, RdiError>where
Self: Sized,
fn get_keyed<T: ?Sized + Sync + Send + 'static>(
&self,
variant: &str,
) -> Result<Arc<T>, RdiError>where
Self: Sized,
Err if not found.Source§fn try_get_keyed<T: ?Sized + Sync + Send + 'static>(
&self,
variant: &str,
) -> Option<Arc<T>>where
Self: Sized,
fn try_get_keyed<T: ?Sized + Sync + Send + 'static>(
&self,
variant: &str,
) -> Option<Arc<T>>where
Self: Sized,
None if not found or
not resolvable at this point (e.g. root scope validation, disposed
provider/scope). Never panics for framework-level failures.Source§fn get_all<T: ?Sized + Sync + Send + 'static>(&self) -> Vec<Arc<T>>where
Self: Sized,
fn get_all<T: ?Sized + Sync + Send + 'static>(&self) -> Vec<Arc<T>>where
Self: Sized,
T, in registration
order. Read moreSource§fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError>where
Self: Sized,
fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError>where
Self: Sized,
T (bypass cache, fresh each call).
Returns Err if not registered or the service is Singleton.Source§fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T>where
Self: Sized,
fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T>where
Self: Sized,
T, returning None if not registered or Singleton.