ServiceProvider

Struct ServiceProvider 

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

The root service provider for resolving services.

This is created by calling ServiceCollection::build() and provides methods to resolve singleton and transient services, as well as create scoped providers.

§Example

use service_rs::ServiceCollection;
use std::sync::Arc;

let mut collection = ServiceCollection::new();
collection.add_singleton_with_factory::<i32, _, _>(|_| async {
    Ok(Box::new(42) as Box<dyn std::any::Any + Send + Sync>)
});
let provider = collection.build();

let value: Arc<i32> = provider.get::<i32>().await.unwrap();

Implementations§

Source§

impl ServiceProvider

Source

pub fn create_scope(self: &Arc<Self>) -> Arc<ScopedServiceProvider>

Creates a new service scope.

Scopes are used to manage scoped service lifetimes. Services registered with ServiceCollection::add_scoped or ServiceCollection::add_scoped_with_factory will have one instance per scope.

§Example
use service_rs::ServiceCollection;

let provider = ServiceCollection::new().build();
let scope = provider.create_scope();
Examples found in repository?
examples/example.rs (line 164)
52async fn main() {
53    let mut collection = ServiceCollection::new();
54    collection.add_singleton_with_factory::<i32, _, _>(|_| async {
55        Ok(Box::new(42) as Box<dyn std::any::Any + Send + Sync>)
56    });
57    collection.add_transient_with_factory::<SomeStringWrapper, _, _>(|_| async {
58        Ok(Box::new(SomeStringWrapper("Hello".to_string()))
59            as Box<dyn std::any::Any + Send + Sync>)
60    });
61    collection.add_scoped_with_factory::<TestDep, _, _>(|_| async {
62        Ok(Box::new(TestDep(42)) as Box<dyn std::any::Any + Send + Sync>)
63    });
64    collection.add_scoped::<DependingDeps>();
65    collection.add_scoped_interface::<dyn SomeInterface, SomeInterfaceImpl>();
66
67    println!("Successfully registered {} services", collection.len());
68
69    let provider = collection.build();
70
71    println!("Successfully built ServiceProvider");
72
73    {
74        match provider.get::<i32>().await {
75            Ok(first) => println!(
76                "(first get attempt) Service with type {} ({:p}) value is {}",
77                std::any::type_name::<i32>(),
78                Arc::as_ptr(&first),
79                first
80            ),
81            Err(e) => println!(
82                "(first get attempt) Failed to get service with type {}: {}",
83                std::any::type_name::<i32>(),
84                e
85            ),
86        }
87
88        match provider.get::<i32>().await {
89            Ok(second) => println!(
90                "(second get attempt) Service with type {} ({:p}) value is {}",
91                std::any::type_name::<i32>(),
92                Arc::as_ptr(&second),
93                second
94            ),
95            Err(e) => println!(
96                "(second get attempt) Failed to get service with type {}: {}",
97                std::any::type_name::<i32>(),
98                e
99            ),
100        }
101    }
102
103    {
104        match provider.get::<SomeStringWrapper>().await {
105            Ok(first) => println!(
106                "(first get attempt) Service with type {} ({:p}) value is {}",
107                std::any::type_name::<SomeStringWrapper>(),
108                Arc::as_ptr(&first),
109                first
110            ),
111            Err(e) => println!(
112                "(first get attempt) Failed to get service with type {}: {}",
113                std::any::type_name::<SomeStringWrapper>(),
114                e
115            ),
116        }
117
118        match provider.get::<SomeStringWrapper>().await {
119            Ok(second) => println!(
120                "(second get attempt) Service with type {} ({:p}) value is {}",
121                std::any::type_name::<SomeStringWrapper>(),
122                Arc::as_ptr(&second),
123                second
124            ),
125            Err(e) => println!(
126                "(second get attempt) Failed to get service with type {}: {}",
127                std::any::type_name::<SomeStringWrapper>(),
128                e
129            ),
130        }
131    }
132
133    {
134        match provider.get::<TestDep>().await {
135            Ok(first) => println!(
136                "(first get attempt) Service with type {} ({:p}) value is {}",
137                std::any::type_name::<TestDep>(),
138                Arc::as_ptr(&first),
139                first
140            ),
141            Err(e) => println!(
142                "(first get attempt) Failed to get service with type {}: {}",
143                std::any::type_name::<TestDep>(),
144                e
145            ),
146        }
147
148        match provider.get::<TestDep>().await {
149            Ok(second) => println!(
150                "(second get attempt) Service with type {} ({:p}) value is {}",
151                std::any::type_name::<TestDep>(),
152                Arc::as_ptr(&second),
153                second
154            ),
155            Err(e) => println!(
156                "(second get attempt) Failed to get service with type {}: {}",
157                std::any::type_name::<TestDep>(),
158                e
159            ),
160        }
161    }
162
163    {
164        let scope = provider.create_scope();
165
166        match scope.get::<TestDep>().await {
167            Ok(first) => println!(
168                "(first get attempt) Service with type {} ({:p}) value is {}",
169                std::any::type_name::<TestDep>(),
170                Arc::as_ptr(&first),
171                first
172            ),
173            Err(e) => println!(
174                "(first get attempt) Failed to get service with type {}: {}",
175                std::any::type_name::<TestDep>(),
176                e
177            ),
178        }
179
180        match scope.get::<TestDep>().await {
181            Ok(second) => println!(
182                "(second get attempt) Service with type {} ({:p}) value is {}",
183                std::any::type_name::<TestDep>(),
184                Arc::as_ptr(&second),
185                second
186            ),
187            Err(e) => println!(
188                "(second get attempt) Failed to get service with type {}: {}",
189                std::any::type_name::<TestDep>(),
190                e
191            ),
192        }
193
194        match scope.get::<DependingDeps>().await {
195            Ok(first) => println!(
196                "(first get attempt) Service with type {} ({:p}) resolved successfully with test_dep at {:p}",
197                std::any::type_name::<DependingDeps>(),
198                Arc::as_ptr(&first),
199                Arc::as_ptr(first.test_dep())
200            ),
201            Err(e) => println!(
202                "(first get attempt) Failed to get service with type {}: {}",
203                std::any::type_name::<DependingDeps>(),
204                e
205            ),
206        }
207
208        match scope.get::<DependingDeps>().await {
209            Ok(second) => println!(
210                "(second get attempt) Service with type {} ({:p}) resolved successfully with test_dep at {:p}",
211                std::any::type_name::<DependingDeps>(),
212                Arc::as_ptr(&second),
213                Arc::as_ptr(second.test_dep())
214            ),
215            Err(e) => println!(
216                "(second get attempt) Failed to get service with type {}: {}",
217                std::any::type_name::<DependingDeps>(),
218                e
219            ),
220        }
221    }
222
223    {
224        match provider
225            .create_scope()
226            .get::<Box<dyn SomeInterface>>()
227            .await
228        {
229            Ok(first) => {
230                println!(
231                    "(first get attempt) Service with type {} ({:p}) resolved successfully",
232                    std::any::type_name::<Box<dyn SomeInterface>>(),
233                    Arc::as_ptr(&first)
234                );
235                first.do_something();
236            }
237            Err(e) => println!(
238                "(first get attempt) Failed to get service with type {}: {}",
239                std::any::type_name::<Box<dyn SomeInterface>>(),
240                e
241            ),
242        }
243    }
244}
Source

pub async fn len(&self) -> usize

Returns the number of resolved service instances currently cached in the provider.

This count includes singleton services that have been instantiated. It does not include services that are registered but not yet resolved.

§Example
use service_rs::ServiceCollection;

let provider = ServiceCollection::new().build();
let count = provider.len().await;
Source

pub fn collection_len(&self) -> usize

Returns the total number of registered service types in the collection.

This count includes all registered services regardless of whether they have been resolved.

§Example
use service_rs::ServiceCollection;

let mut collection = ServiceCollection::new();
collection.add_singleton_with_factory::<i32, _, _>(|_| async {
    Ok(Box::new(42) as Box<dyn std::any::Any + Send + Sync>)
});
let provider = collection.build();
assert_eq!(provider.collection_len(), 1);
Source

pub async fn is_empty(&self) -> bool

Returns true if no service instances have been resolved yet.

This checks whether the provider’s instance cache is empty, not whether services are registered in the collection.

§Example
use service_rs::ServiceCollection;

let provider = ServiceCollection::new().build();
assert!(provider.is_empty().await);
Source

pub async fn get<T>(self: &Arc<Self>) -> Result<Arc<T>, ServiceError>
where T: Send + Sync + 'static,

Resolves a service from the provider.

Returns an Arc<T> containing the resolved service instance.

§Errors
§Example
use service_rs::ServiceCollection;
use std::sync::Arc;

let mut collection = ServiceCollection::new();
collection.add_singleton_with_factory::<i32, _, _>(|_| async {
    Ok(Box::new(42) as Box<dyn std::any::Any + Send + Sync>)
});
let provider = collection.build();

let value: Arc<i32> = provider.get::<i32>().await.unwrap();
assert_eq!(*value, 42);
Examples found in repository?
examples/example.rs (line 74)
52async fn main() {
53    let mut collection = ServiceCollection::new();
54    collection.add_singleton_with_factory::<i32, _, _>(|_| async {
55        Ok(Box::new(42) as Box<dyn std::any::Any + Send + Sync>)
56    });
57    collection.add_transient_with_factory::<SomeStringWrapper, _, _>(|_| async {
58        Ok(Box::new(SomeStringWrapper("Hello".to_string()))
59            as Box<dyn std::any::Any + Send + Sync>)
60    });
61    collection.add_scoped_with_factory::<TestDep, _, _>(|_| async {
62        Ok(Box::new(TestDep(42)) as Box<dyn std::any::Any + Send + Sync>)
63    });
64    collection.add_scoped::<DependingDeps>();
65    collection.add_scoped_interface::<dyn SomeInterface, SomeInterfaceImpl>();
66
67    println!("Successfully registered {} services", collection.len());
68
69    let provider = collection.build();
70
71    println!("Successfully built ServiceProvider");
72
73    {
74        match provider.get::<i32>().await {
75            Ok(first) => println!(
76                "(first get attempt) Service with type {} ({:p}) value is {}",
77                std::any::type_name::<i32>(),
78                Arc::as_ptr(&first),
79                first
80            ),
81            Err(e) => println!(
82                "(first get attempt) Failed to get service with type {}: {}",
83                std::any::type_name::<i32>(),
84                e
85            ),
86        }
87
88        match provider.get::<i32>().await {
89            Ok(second) => println!(
90                "(second get attempt) Service with type {} ({:p}) value is {}",
91                std::any::type_name::<i32>(),
92                Arc::as_ptr(&second),
93                second
94            ),
95            Err(e) => println!(
96                "(second get attempt) Failed to get service with type {}: {}",
97                std::any::type_name::<i32>(),
98                e
99            ),
100        }
101    }
102
103    {
104        match provider.get::<SomeStringWrapper>().await {
105            Ok(first) => println!(
106                "(first get attempt) Service with type {} ({:p}) value is {}",
107                std::any::type_name::<SomeStringWrapper>(),
108                Arc::as_ptr(&first),
109                first
110            ),
111            Err(e) => println!(
112                "(first get attempt) Failed to get service with type {}: {}",
113                std::any::type_name::<SomeStringWrapper>(),
114                e
115            ),
116        }
117
118        match provider.get::<SomeStringWrapper>().await {
119            Ok(second) => println!(
120                "(second get attempt) Service with type {} ({:p}) value is {}",
121                std::any::type_name::<SomeStringWrapper>(),
122                Arc::as_ptr(&second),
123                second
124            ),
125            Err(e) => println!(
126                "(second get attempt) Failed to get service with type {}: {}",
127                std::any::type_name::<SomeStringWrapper>(),
128                e
129            ),
130        }
131    }
132
133    {
134        match provider.get::<TestDep>().await {
135            Ok(first) => println!(
136                "(first get attempt) Service with type {} ({:p}) value is {}",
137                std::any::type_name::<TestDep>(),
138                Arc::as_ptr(&first),
139                first
140            ),
141            Err(e) => println!(
142                "(first get attempt) Failed to get service with type {}: {}",
143                std::any::type_name::<TestDep>(),
144                e
145            ),
146        }
147
148        match provider.get::<TestDep>().await {
149            Ok(second) => println!(
150                "(second get attempt) Service with type {} ({:p}) value is {}",
151                std::any::type_name::<TestDep>(),
152                Arc::as_ptr(&second),
153                second
154            ),
155            Err(e) => println!(
156                "(second get attempt) Failed to get service with type {}: {}",
157                std::any::type_name::<TestDep>(),
158                e
159            ),
160        }
161    }
162
163    {
164        let scope = provider.create_scope();
165
166        match scope.get::<TestDep>().await {
167            Ok(first) => println!(
168                "(first get attempt) Service with type {} ({:p}) value is {}",
169                std::any::type_name::<TestDep>(),
170                Arc::as_ptr(&first),
171                first
172            ),
173            Err(e) => println!(
174                "(first get attempt) Failed to get service with type {}: {}",
175                std::any::type_name::<TestDep>(),
176                e
177            ),
178        }
179
180        match scope.get::<TestDep>().await {
181            Ok(second) => println!(
182                "(second get attempt) Service with type {} ({:p}) value is {}",
183                std::any::type_name::<TestDep>(),
184                Arc::as_ptr(&second),
185                second
186            ),
187            Err(e) => println!(
188                "(second get attempt) Failed to get service with type {}: {}",
189                std::any::type_name::<TestDep>(),
190                e
191            ),
192        }
193
194        match scope.get::<DependingDeps>().await {
195            Ok(first) => println!(
196                "(first get attempt) Service with type {} ({:p}) resolved successfully with test_dep at {:p}",
197                std::any::type_name::<DependingDeps>(),
198                Arc::as_ptr(&first),
199                Arc::as_ptr(first.test_dep())
200            ),
201            Err(e) => println!(
202                "(first get attempt) Failed to get service with type {}: {}",
203                std::any::type_name::<DependingDeps>(),
204                e
205            ),
206        }
207
208        match scope.get::<DependingDeps>().await {
209            Ok(second) => println!(
210                "(second get attempt) Service with type {} ({:p}) resolved successfully with test_dep at {:p}",
211                std::any::type_name::<DependingDeps>(),
212                Arc::as_ptr(&second),
213                Arc::as_ptr(second.test_dep())
214            ),
215            Err(e) => println!(
216                "(second get attempt) Failed to get service with type {}: {}",
217                std::any::type_name::<DependingDeps>(),
218                e
219            ),
220        }
221    }
222
223    {
224        match provider
225            .create_scope()
226            .get::<Box<dyn SomeInterface>>()
227            .await
228        {
229            Ok(first) => {
230                println!(
231                    "(first get attempt) Service with type {} ({:p}) resolved successfully",
232                    std::any::type_name::<Box<dyn SomeInterface>>(),
233                    Arc::as_ptr(&first)
234                );
235                first.do_something();
236            }
237            Err(e) => println!(
238                "(first get attempt) Failed to get service with type {}: {}",
239                std::any::type_name::<Box<dyn SomeInterface>>(),
240                e
241            ),
242        }
243    }
244}

Trait Implementations§

Source§

impl Debug for ServiceProvider

Source§

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

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

impl Default for ServiceProvider

Source§

fn default() -> ServiceProvider

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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.