pub struct ServiceCollection { /* private fields */ }Expand description
Represents a service collection.
Implementations§
Source§impl ServiceCollection
impl ServiceCollection
Sourcepub fn remove(&mut self, index: usize) -> ServiceDescriptor
pub fn remove(&mut self, index: usize) -> ServiceDescriptor
Sourcepub fn add<T: Into<ServiceDescriptor>>(&mut self, descriptor: T) -> &mut Self
pub fn add<T: Into<ServiceDescriptor>>(&mut self, descriptor: T) -> &mut Self
Adds a service using the specified service descriptor.
§Arguments
descriptor- The ServiceDescriptor to register
Sourcepub fn try_add<T: Into<ServiceDescriptor>>(
&mut self,
descriptor: T,
) -> &mut Self
pub fn try_add<T: Into<ServiceDescriptor>>( &mut self, descriptor: T, ) -> &mut Self
Adds a service using the specified service descriptor if the service has not already been registered.
§Arguments
descriptor- The ServiceDescriptor to register
Sourcepub fn try_add_to_all<T: Into<ServiceDescriptor>>(
&mut self,
descriptor: T,
) -> &mut Self
pub fn try_add_to_all<T: Into<ServiceDescriptor>>( &mut self, descriptor: T, ) -> &mut Self
Adds a service using the specified service descriptor if the service with same service and implementation type has not already been registered.
§Arguments
descriptor- The ServiceDescriptor to register
Sourcepub fn try_add_all(
&mut self,
descriptors: impl IntoIterator<Item = ServiceDescriptor>,
) -> &mut Self
pub fn try_add_all( &mut self, descriptors: impl IntoIterator<Item = ServiceDescriptor>, ) -> &mut Self
Adds the specified service descriptors if each of the services are not already registered with the same service and implementation type.
§Arguments
descriptors- The ServiceDescriptor sequence to register
Sourcepub fn replace<T: Into<ServiceDescriptor>>(
&mut self,
descriptor: T,
) -> &mut Self
pub fn replace<T: Into<ServiceDescriptor>>( &mut self, descriptor: T, ) -> &mut Self
Removes the first service descriptor with the same service type and adds the replacement.
§Arguments
descriptor- The replacement ServiceDescriptor
Sourcepub fn try_replace<T: Into<ServiceDescriptor>>(
&mut self,
descriptor: T,
) -> &mut Self
pub fn try_replace<T: Into<ServiceDescriptor>>( &mut self, descriptor: T, ) -> &mut Self
Adds or replaces a service with the specified descriptor if the service has not already been registered.
§Arguments
descriptor- The replacement ServiceDescriptor
Sourcepub fn remove_all<T: Any + ?Sized>(&mut self) -> &mut Self
pub fn remove_all<T: Any + ?Sized>(&mut self) -> &mut Self
Removes all specified descriptors of the specified type.
Sourcepub fn build_provider(&self) -> Result<ServiceProvider, ValidationError>
pub fn build_provider(&self) -> Result<ServiceProvider, ValidationError>
Builds and returns a new ServiceProvider.
Sourcepub fn iter(
&self,
) -> impl ExactSizeIterator<Item = &ServiceDescriptor> + DoubleEndedIterator
pub fn iter( &self, ) -> impl ExactSizeIterator<Item = &ServiceDescriptor> + DoubleEndedIterator
Gets a read-only iterator for the collection
Sourcepub fn decorate<TSvc: ?Sized + Any, TImpl>(
&mut self,
activate: impl Fn(&ServiceProvider, Ref<TSvc>) -> Ref<TSvc> + 'static,
) -> &mut Self
pub fn decorate<TSvc: ?Sized + Any, TImpl>( &mut self, activate: impl Fn(&ServiceProvider, Ref<TSvc>) -> Ref<TSvc> + 'static, ) -> &mut Self
Decorates an existing service descriptor with a new one that wraps the original.
§Arguments
activate- The function that will be called to decorate the resolved service instance
§Remarks
This function will only decorate the last registered ServiceDescriptor for the specified service type. If
there are multiple, the others are ignored. If you need to decorate all services of a particular service
type, consider using decorate_all instead. If the service to be decorated is not
registered, this function does nothing. The decorator ServiceDescriptor is created with the same
lifetime as the original service registration. The implementation type of the
decorator is determined by the generic parameter TImpl. If the original and decorator implementation types
are the same, the original, decorated ServiceDescriptor is not replaced to prevent infinite recursion.
§Example
use di::{injectable, Injectable, ServiceCollection, Ref};
trait Counter {
fn count(&self) -> usize;
}
#[injectable(Counter)]
struct SingleCount;
impl Counter for SingleCount {
fn count(&self) -> usize {
1
}
}
struct DoubleCount(Ref<dyn Counter>);
impl Counter for DoubleCount {
fn count(&self) -> usize {
self.0.count() * 2
}
}
let provider = ServiceCollection::new()
.add(SingleCount::transient())
.decorate::<dyn Counter, DoubleCount>(|_, decorated| Ref::new(DoubleCount(decorated)))
.build_provider()
.unwrap();
let counter = provider.get_required::<dyn Counter>();
assert_eq!(counter.count(), 2);Sourcepub fn decorate_all<TSvc: ?Sized + Any, TImpl>(
&mut self,
activate: impl Fn(&ServiceProvider, Ref<TSvc>) -> Ref<TSvc> + 'static,
) -> &mut Self
pub fn decorate_all<TSvc: ?Sized + Any, TImpl>( &mut self, activate: impl Fn(&ServiceProvider, Ref<TSvc>) -> Ref<TSvc> + 'static, ) -> &mut Self
Decorates all existing service descriptors with a new one that wraps the original.
§Arguments
activate- The function that will be called to decorate the resolved service instance
§Remarks
This function decorates all registered ServiceDescriptor instances for the specified service type. If there are none, this function does nothing. The decorator ServiceDescriptor is created with the same lifetime as the original. If the original, decorated ServiceDescriptor is the same the decorator type, it is ignored.
§Example
use di::{injectable, Injectable, ServiceCollection, Ref};
use std::sync::atomic::{AtomicUsize, Ordering};
trait Feature {
fn show(&self);
}
#[injectable(Feature)]
struct Feature1;
impl Feature for Feature1 {
fn show(&self) {
}
}
#[injectable(Feature)]
struct Feature2;
impl Feature for Feature2 {
fn show(&self) {
}
}
#[injectable]
struct Tracker(AtomicUsize);
impl Tracker {
fn track(&self) {
self.0.fetch_add(1, Ordering::Relaxed);
}
fn count(&self) -> usize {
self.0.load(Ordering::Relaxed)
}
}
struct FeatureTracker {
feature: Ref<dyn Feature>,
tracker: Ref<Tracker>,
};
impl Feature for FeatureTracker {
fn show(&self) {
self.tracker.track();
self.feature.show();
}
}
let provider = ServiceCollection::new()
.add(Tracker::singleton())
.try_add_to_all(Feature1::transient())
.try_add_to_all(Feature2::transient())
.decorate_all::<dyn Feature, FeatureTracker>(|sp, decorated| {
Ref::new(FeatureTracker { feature: decorated, tracker: sp.get_required::<Tracker>() })
})
.build_provider()
.unwrap();
let features = provider.get_all::<dyn Feature>();
let tracker = provider.get_required::<Tracker>();
for feature in features {
feature.show();
}
assert_eq!(tracker.count(), 2);