Skip to main content

ServiceCollection

Struct ServiceCollection 

Source
pub struct ServiceCollection { /* private fields */ }
Expand description

Services registered for an application, frozen into a ServiceProvider by build.

Registering a type again adds another registration: a single resolve uses the last one, and resolve_all returns every one in order. Singletons are constructed outside any scope, so a singleton that depends on a scoped service fails to resolve rather than holding on to one scope’s instance. Transients are constructed in the scope that requested them.

§Validation

build always rejects dependency cycles. Two more checks are opt-in, and every problem found is reported in one BuildError:

use hosting_di::{BuildIssue, ServiceCollection};
let mut services = ServiceCollection::new();
services
    .validate_dependencies()
    .validate_scopes()
    .add_singleton::<Database>(); // needs a Pool, which isn't registered

let err = services.build().unwrap_err();
assert!(matches!(err.issues(), [BuildIssue::MissingDependency { .. }]));

Implementations§

Source§

impl ServiceCollection

Source

pub fn new() -> Self

Creates an empty collection.

Source

pub fn add_singleton<T: Service>(&mut self) -> &mut Self

Registers T with one instance shared for the life of the provider.

Source

pub fn add_scoped<T: Service>(&mut self) -> &mut Self

Registers T with one instance per scope.

Source

pub fn add_transient<T: Service>(&mut self) -> &mut Self

Registers T with a new instance on every resolution.

Source

pub fn add_singleton_as<I, T>(&mut self) -> &mut Self
where I: ?Sized + CastFrom<T> + Send + Sync + 'static, T: Service,

Registers T as an implementation of the trait object I, with one instance shared for the life of the provider.

T is reachable only as I; register it separately to resolve it by its own type.

Source

pub fn add_scoped_as<I, T>(&mut self) -> &mut Self
where I: ?Sized + CastFrom<T> + Send + Sync + 'static, T: Service,

Registers T as an implementation of I, with one instance per scope.

Source

pub fn add_transient_as<I, T>(&mut self) -> &mut Self
where I: ?Sized + CastFrom<T> + Send + Sync + 'static, T: Service,

Registers T as an implementation of I, constructed on every resolution.

Source

pub fn contains<T: ?Sized + 'static>(&self) -> bool

Whether anything is registered as T.

Covers every form of registration, so it can guard any of them, for example to add a default only when the application hasn’t.

Source

pub fn try_add_singleton<T: Service>(&mut self) -> &mut Self

Like add_singleton, but only if nothing is registered as T yet.

Source

pub fn try_add_scoped<T: Service>(&mut self) -> &mut Self

Like add_scoped, but only if nothing is registered as T yet.

Source

pub fn try_add_transient<T: Service>(&mut self) -> &mut Self

Like add_transient, but only if nothing is registered as T yet.

Source

pub fn try_add_singleton_as<I, T>(&mut self) -> &mut Self
where I: ?Sized + CastFrom<T> + Send + Sync + 'static, T: Service,

Like add_singleton_as, but only if nothing is registered as I yet, whatever its implementation.

Source

pub fn try_add_scoped_as<I, T>(&mut self) -> &mut Self
where I: ?Sized + CastFrom<T> + Send + Sync + 'static, T: Service,

Like add_scoped_as, but only if nothing is registered as I yet, whatever its implementation.

Source

pub fn try_add_transient_as<I, T>(&mut self) -> &mut Self
where I: ?Sized + CastFrom<T> + Send + Sync + 'static, T: Service,

Like add_transient_as, but only if nothing is registered as I yet, whatever its implementation.

Source

pub fn add_singleton_with<T, F>(&mut self, factory: F) -> &mut Self
where T: Send + Sync + 'static, F: Fn(&Resolver<'_>) -> Result<T, BoxError> + Send + Sync + 'static,

Registers a factory for T with one instance shared for the life of the provider.

Errors from resolving dependencies inside the factory keep their original path; any other error is reported as a construction failure of T. Like constructors, factories must not block on other threads that resolve from the same container.

Source

pub fn add_scoped_with<T, F>(&mut self, factory: F) -> &mut Self
where T: Send + Sync + 'static, F: Fn(&Resolver<'_>) -> Result<T, BoxError> + Send + Sync + 'static,

Registers a factory for T with one instance per scope.

Source

pub fn add_transient_with<T, F>(&mut self, factory: F) -> &mut Self
where T: Send + Sync + 'static, F: Fn(&Resolver<'_>) -> Result<T, BoxError> + Send + Sync + 'static,

Registers a factory for T that runs on every resolution.

Source

pub fn add_singleton_instance<T: Send + Sync + 'static>( &mut self, instance: T, ) -> &mut Self

Registers an already constructed singleton.

Source

pub fn add_singleton_as_with<I, F>(&mut self, factory: F) -> &mut Self
where I: ?Sized + Send + Sync + 'static, F: Fn(&Resolver<'_>) -> Result<Arc<I>, BoxError> + Send + Sync + 'static,

Registers a factory producing the trait object I, with one instance shared for the life of the provider.

Unlike add_singleton_as, the trait needs no #[abstraction], so traits from other crates can be registered. The concrete type behind the returned Arc is not known, so errors and logs name these registrations by I.

Source

pub fn add_scoped_as_with<I, F>(&mut self, factory: F) -> &mut Self
where I: ?Sized + Send + Sync + 'static, F: Fn(&Resolver<'_>) -> Result<Arc<I>, BoxError> + Send + Sync + 'static,

Registers a factory producing the trait object I, with one instance per scope.

Source

pub fn add_transient_as_with<I, F>(&mut self, factory: F) -> &mut Self
where I: ?Sized + Send + Sync + 'static, F: Fn(&Resolver<'_>) -> Result<Arc<I>, BoxError> + Send + Sync + 'static,

Registers a factory producing the trait object I, run on every resolution.

The returned Arc is stored behind one more allocation, so each resolution allocates once beyond what the factory does.

Source

pub fn add_singleton_instance_as<I>(&mut self, instance: Arc<I>) -> &mut Self
where I: ?Sized + Send + Sync + 'static,

Registers an already constructed trait object as a singleton.

Source

pub fn validate_dependencies(&mut self) -> &mut Self

Rejects at build any declared dependency that has no registration.

Without it, a missing dependency surfaces when the service is first resolved. A Vec<Arc<T>> dependency is never missing, since it may be empty, and factories are not checked because their dependencies are not declared.

Source

pub fn validate_scopes(&mut self) -> &mut Self

Rejects at build any singleton that depends on a scoped service, directly or through transients.

Without it, such a singleton fails to resolve with ResolveError::ScopedFromRoot; it never silently keeps one scope’s instance.

Source

pub fn build(self) -> Result<ServiceProvider, BuildError>

Freezes the registrations into a provider.

Fails if registered services depend on each other in a cycle, or if an enabled check finds a problem; every problem found is reported.

Trait Implementations§

Source§

impl Debug for ServiceCollection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ServiceCollection

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.