pub struct Registry<S> { /* private fields */ }Expand description
Type-erased provider registry used for service discovery and DI-style lookup.
Registration happens during bootstrap and runtime access is read-only via typed resolves.
We keep the underlying maps behind RwLock<HashMap<..>> so registration stays simple while
lookup only holds a short-lived read lock long enough to clone the stored Arc.
Implementations§
Source§impl<S: 'static> Registry<S>
impl<S: 'static> Registry<S>
Sourcepub fn insert<P>(&self, item: Arc<P>) -> Result<&Self>where
P: Provider<S> + 'static,
pub fn insert<P>(&self, item: Arc<P>) -> Result<&Self>where
P: Provider<S> + 'static,
Register a provider into the registry.
This accepts Arc<P> where P: Provider. The service is stored as a
type-erased Arc<dyn Provider> but continues to point to the same underlying
allocation (no new allocation is created).
If another service with the same concrete type is already registered, registration is rejected.
Returns &Self to allow fallible fluent chaining:
registry
.insert(dns.clone())?
.insert(ipc.clone())?;Sourcepub fn bind_dyn<I, P>(
&self,
cast: impl FnOnce(Arc<P>) -> Arc<I>,
) -> Result<&Self>
pub fn bind_dyn<I, P>( &self, cast: impl FnOnce(Arc<P>) -> Arc<I>, ) -> Result<&Self>
Bind a registered concrete provider as a trait-object capability.
This does not register a second lifecycle provider. It resolves the
existing concrete provider P, casts the same Arc<P> into Arc<I>,
and stores that trait-object handle under TypeId::of::<I>().
Returns an error if P has not been registered yet. If I already has
a binding, the new binding replaces it.
Sourcepub fn with_typed<T, R>(&self, f: impl FnOnce(&T) -> R) -> Option<R>where
T: Provider<S> + 'static,
pub fn with_typed<T, R>(&self, f: impl FnOnce(&T) -> R) -> Option<R>where
T: Provider<S> + 'static,
Execute a closure with a concrete typed reference &T if the service is registered.
Sourcepub fn resolve<T>(&self) -> Option<Arc<T>>where
T: Provider<S> + 'static,
pub fn resolve<T>(&self) -> Option<Arc<T>>where
T: Provider<S> + 'static,
Resolve a concrete service as an owned Arc<T> handle.
This is the DI-style, high-level API: it returns a typed Arc<T> that
points to the same underlying allocation as the internally registered
provider (no new Arc allocation). The returned Arc is obtained by
downcasting from a type-indexed map (TypeId).
Returns None if the type is not registered.
Sourcepub fn resolve_dyn<I>(&self) -> Option<Arc<I>>
pub fn resolve_dyn<I>(&self) -> Option<Arc<I>>
Resolve a trait-object capability bound with bind_dyn.
Sourcepub fn providers(&self) -> Vec<Arc<dyn Provider<S>>>
pub fn providers(&self) -> Vec<Arc<dyn Provider<S>>>
Return a snapshot of registered providers.
Sourcepub fn list_names(&self) -> Vec<&'static str>
pub fn list_names(&self) -> Vec<&'static str>
Return the list of provider display names (for diagnostics only).
Sourcepub fn lifecycle_names(&self) -> Result<Vec<&'static str>>
pub fn lifecycle_names(&self) -> Result<Vec<&'static str>>
Return provider display names in lifecycle order.
This is useful for diagnostics and startup logging before running
boot_all().
Sourcepub fn validate_all(&self, state: &S) -> Result<ValidationOutcome>
pub fn validate_all(&self, state: &S) -> Result<ValidationOutcome>
Run validate for every provider in lifecycle order.
Lifecycle-plan failures remain outer errors. A provider validation failure does not prevent later providers from being checked; every provider failure is retained in the outcome.
pub async fn boot_all(&self, state: &S) -> Result<()>
Sourcepub async fn finalize_all(&self, state: &S) -> Result<FinalizeOutcome>
pub async fn finalize_all(&self, state: &S) -> Result<FinalizeOutcome>
Run Finalizable::finalize for every provider that exposes the
capability, in reverse lifecycle order. Called by the bootstrap
layer after the runnable tasks have drained. One failure does not stop
later finalizers; every failure is retained in the outcome.