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
impl ServiceCollection
Sourcepub fn add_singleton<T: Service>(&mut self) -> &mut Self
pub fn add_singleton<T: Service>(&mut self) -> &mut Self
Registers T with one instance shared for the life of the provider.
Sourcepub fn add_scoped<T: Service>(&mut self) -> &mut Self
pub fn add_scoped<T: Service>(&mut self) -> &mut Self
Registers T with one instance per scope.
Sourcepub fn add_transient<T: Service>(&mut self) -> &mut Self
pub fn add_transient<T: Service>(&mut self) -> &mut Self
Registers T with a new instance on every resolution.
Sourcepub fn add_singleton_as<I, T>(&mut self) -> &mut Self
pub fn add_singleton_as<I, T>(&mut self) -> &mut Self
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.
Sourcepub fn add_scoped_as<I, T>(&mut self) -> &mut Self
pub fn add_scoped_as<I, T>(&mut self) -> &mut Self
Registers T as an implementation of I, with one instance per scope.
Sourcepub fn add_transient_as<I, T>(&mut self) -> &mut Self
pub fn add_transient_as<I, T>(&mut self) -> &mut Self
Registers T as an implementation of I, constructed on every
resolution.
Sourcepub fn contains<T: ?Sized + 'static>(&self) -> bool
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.
Sourcepub fn try_add_singleton<T: Service>(&mut self) -> &mut Self
pub fn try_add_singleton<T: Service>(&mut self) -> &mut Self
Like add_singleton, but only if nothing is
registered as T yet.
Sourcepub fn try_add_scoped<T: Service>(&mut self) -> &mut Self
pub fn try_add_scoped<T: Service>(&mut self) -> &mut Self
Like add_scoped, but only if nothing is
registered as T yet.
Sourcepub fn try_add_transient<T: Service>(&mut self) -> &mut Self
pub fn try_add_transient<T: Service>(&mut self) -> &mut Self
Like add_transient, but only if nothing is
registered as T yet.
Sourcepub fn try_add_singleton_as<I, T>(&mut self) -> &mut Self
pub fn try_add_singleton_as<I, T>(&mut self) -> &mut Self
Like add_singleton_as, but only if nothing
is registered as I yet, whatever its implementation.
Sourcepub fn try_add_scoped_as<I, T>(&mut self) -> &mut Self
pub fn try_add_scoped_as<I, T>(&mut self) -> &mut Self
Like add_scoped_as, but only if nothing is
registered as I yet, whatever its implementation.
Sourcepub fn try_add_transient_as<I, T>(&mut self) -> &mut Self
pub fn try_add_transient_as<I, T>(&mut self) -> &mut Self
Like add_transient_as, but only if nothing
is registered as I yet, whatever its implementation.
Sourcepub fn add_singleton_with<T, F>(&mut self, factory: F) -> &mut Self
pub fn add_singleton_with<T, F>(&mut self, factory: F) -> &mut Self
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.
Sourcepub fn add_scoped_with<T, F>(&mut self, factory: F) -> &mut Self
pub fn add_scoped_with<T, F>(&mut self, factory: F) -> &mut Self
Registers a factory for T with one instance per scope.
Sourcepub fn add_transient_with<T, F>(&mut self, factory: F) -> &mut Self
pub fn add_transient_with<T, F>(&mut self, factory: F) -> &mut Self
Registers a factory for T that runs on every resolution.
Sourcepub fn add_singleton_instance<T: Send + Sync + 'static>(
&mut self,
instance: T,
) -> &mut Self
pub fn add_singleton_instance<T: Send + Sync + 'static>( &mut self, instance: T, ) -> &mut Self
Registers an already constructed singleton.
Sourcepub fn add_singleton_as_with<I, F>(&mut self, factory: F) -> &mut Self
pub fn add_singleton_as_with<I, F>(&mut self, factory: F) -> &mut Self
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.
Sourcepub fn add_scoped_as_with<I, F>(&mut self, factory: F) -> &mut Self
pub fn add_scoped_as_with<I, F>(&mut self, factory: F) -> &mut Self
Registers a factory producing the trait object I, with one instance
per scope.
Sourcepub fn add_transient_as_with<I, F>(&mut self, factory: F) -> &mut Self
pub fn add_transient_as_with<I, F>(&mut self, factory: F) -> &mut Self
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.
Sourcepub fn add_singleton_instance_as<I>(&mut self, instance: Arc<I>) -> &mut Self
pub fn add_singleton_instance_as<I>(&mut self, instance: Arc<I>) -> &mut Self
Registers an already constructed trait object as a singleton.
Sourcepub fn validate_dependencies(&mut self) -> &mut Self
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.
Sourcepub fn validate_scopes(&mut self) -> &mut Self
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.
Sourcepub fn build(self) -> Result<ServiceProvider, BuildError>
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.