1use crate::*;
8use ferroui_system::{threading::tasks::Task, IDisposable};
9use std::cell::{Cell, RefCell};
10use std::collections::{HashMap, HashSet};
11use std::rc::{Rc, Weak};
12
13#[derive(Clone, Copy, Debug, Default)]
14pub struct ServiceProviderOptions {
15 pub validate_scopes: bool,
16 pub validate_on_build: bool,
17}
18
19pub trait IServiceProvider {
20 fn ensure_active(&self) -> ServiceResult<()> {
21 Ok(())
22 }
23 fn required_service_provider(&self) -> Option<&dyn ISupportRequiredService> {
25 None
26 }
27 fn disposable(&self) -> Option<&dyn IDisposable> {
28 None
29 }
30 fn required_service_erased(&self, id: &ServiceIdentifier) -> ServiceResult<ErasedService> {
31 if let Some(provider) = self.required_service_provider() {
32 provider.get_required_service_erased(id)
33 } else {
34 self.get_service_erased(id)?
35 .ok_or_else(|| ServiceError::MissingService(id.clone()))
36 }
37 }
38 fn get_service_erased(&self, id: &ServiceIdentifier) -> ServiceResult<Option<ErasedService>>;
39 fn get_services_erased(&self, id: &ServiceIdentifier) -> ServiceResult<Vec<ErasedService>>;
40}
41pub trait ISupportRequiredService: IServiceProvider {
43 fn get_required_service_erased(&self, id: &ServiceIdentifier) -> ServiceResult<ErasedService> {
44 self.get_service_erased(id)?
45 .ok_or_else(|| ServiceError::MissingService(id.clone()))
46 }
47}
48impl ISupportRequiredService for ServiceProvider {}
49pub trait IKeyedServiceProvider: IServiceProvider {
50 fn get_keyed_service_erased(
51 &self,
52 service_type: ServiceType,
53 key: Option<ServiceKey>,
54 ) -> ServiceResult<Option<ErasedService>> {
55 self.get_service_erased(&ServiceIdentifier {
56 service_type,
57 service_key: key,
58 })
59 }
60 fn get_required_keyed_service_erased(
61 &self,
62 service_type: ServiceType,
63 key: Option<ServiceKey>,
64 ) -> ServiceResult<ErasedService> {
65 let id = ServiceIdentifier {
66 service_type,
67 service_key: key,
68 };
69 self.get_service_erased(&id)?
70 .ok_or(ServiceError::MissingService(id))
71 }
72}
73pub trait IServiceProviderIsService {
74 fn is_service(&self, service_type: ServiceType) -> bool;
75}
76pub trait IServiceProviderIsKeyedService {
77 fn is_keyed_service(&self, service_type: ServiceType, key: Option<&ServiceKey>) -> bool;
78}
79pub trait IServiceScopeFactory {
80 fn create_scope(&self) -> ServiceResult<ServiceScope>;
81 fn create_async_scope(&self) -> ServiceResult<AsyncServiceScope> {
82 Ok(AsyncServiceScope::new(Rc::new(self.create_scope()?)))
83 }
84}
85pub trait IServiceScope: IDisposable {
86 fn service_provider(&self) -> &ServiceProvider;
87 fn async_disposable(&self) -> Option<&dyn IAsyncDisposable> {
88 None
89 }
90 fn dispose_scope(&self) -> ServiceResult<()> {
91 self.dispose();
92 Ok(())
93 }
94}
95
96pub trait ServiceProviderServiceExtensions: IServiceProvider {
97 fn create_scope(&self) -> ServiceResult<ServiceScope> {
98 self.get_required_service::<dyn IServiceScopeFactory>()?
99 .create_scope()
100 }
101 fn create_async_scope(&self) -> ServiceResult<AsyncServiceScope> {
102 Ok(AsyncServiceScope::new(Rc::new(self.create_scope()?)))
103 }
104 fn get_service<S: ?Sized + 'static>(&self) -> ServiceResult<Option<Rc<S>>> {
105 self.get_keyed_service::<S>(None)
106 }
107 fn get_required_service<S: ?Sized + 'static>(&self) -> ServiceResult<Rc<S>> {
108 let value = self.required_service_erased(&ServiceIdentifier::of::<S>())?;
109 unerase_service(&value).ok_or(ServiceError::TypeMismatch(ServiceType::of::<S>()))
110 }
111 fn get_services<S: ?Sized + 'static>(&self) -> ServiceResult<Vec<Rc<S>>> {
112 self.get_keyed_services::<S>(None)
113 }
114 fn get_keyed_service<S: ?Sized + 'static>(
115 &self,
116 key: Option<&ServiceKey>,
117 ) -> ServiceResult<Option<Rc<S>>> {
118 self.get_service_erased(&ServiceIdentifier::keyed::<S>(key.cloned()))?
119 .map(|v| unerase_service(&v).ok_or(ServiceError::TypeMismatch(ServiceType::of::<S>())))
120 .transpose()
121 }
122 fn get_required_keyed_service<S: ?Sized + 'static>(
123 &self,
124 key: Option<&ServiceKey>,
125 ) -> ServiceResult<Rc<S>> {
126 self.get_keyed_service::<S>(key)?.ok_or_else(|| {
127 ServiceError::MissingService(ServiceIdentifier::keyed::<S>(key.cloned()))
128 })
129 }
130 fn get_keyed_services<S: ?Sized + 'static>(
131 &self,
132 key: Option<&ServiceKey>,
133 ) -> ServiceResult<Vec<Rc<S>>> {
134 self.get_services_erased(&ServiceIdentifier::keyed::<S>(key.cloned()))?
135 .iter()
136 .map(|v| unerase_service(v).ok_or(ServiceError::TypeMismatch(ServiceType::of::<S>())))
137 .collect()
138 }
139}
140impl<T: IServiceProvider + ?Sized> ServiceProviderServiceExtensions for T {}
141
142#[derive(Clone, Debug, PartialEq, Eq, Hash)]
143struct CacheKey {
144 index: usize,
145 key: Option<ServiceKey>,
146}
147struct Captured {
148 value: ErasedService,
149 dispose: Option<crate::service_descriptor::Dispose>,
150 dispose_async: Option<crate::service_descriptor::DisposeAsync>,
151}
152#[derive(Default)]
153struct ScopeState {
154 disposed: Cell<bool>,
155 provider: RefCell<Option<Weak<dyn IServiceProvider>>>,
156 keyed_provider: RefCell<Option<Weak<dyn IKeyedServiceProvider>>>,
157 scope_factory: RefCell<Option<Weak<dyn IServiceScopeFactory>>>,
158 is_service: RefCell<Option<Weak<dyn IServiceProviderIsService>>>,
159 is_keyed_service: RefCell<Option<Weak<dyn IServiceProviderIsKeyedService>>>,
160 cache: RefCell<HashMap<CacheKey, ErasedService>>,
161 disposables: RefCell<Vec<Captured>>,
162}
163const MAX_VALIDATED: usize = 4096;
165struct Root {
166 descriptors: Vec<ServiceDescriptor>,
167 lookup: HashMap<ServiceIdentifier, Vec<usize>>,
168 options: ServiceProviderOptions,
169 scope: Rc<ScopeState>,
170 resolving: RefCell<Vec<(CacheKey, usize)>>,
171 validated: RefCell<HashSet<(CacheKey, bool)>>,
172}
173#[derive(Clone)]
176pub struct ServiceProvider {
177 root: Rc<Root>,
178 scope: Rc<ScopeState>,
179}
180#[derive(Clone)]
181pub struct ServiceScope {
182 provider: ServiceProvider,
183}
184#[derive(Clone)]
186pub struct AsyncServiceScope {
187 scope: Rc<dyn IServiceScope>,
188}
189impl AsyncServiceScope {
190 pub fn new(scope: Rc<dyn IServiceScope>) -> Self {
191 Self { scope }
192 }
193 pub fn service_provider(&self) -> &ServiceProvider {
194 self.scope.service_provider()
195 }
196 pub fn dispose(&self) -> ServiceResult<()> {
197 self.scope.dispose_scope()
198 }
199 pub fn dispose_async(&self) -> Task<()> {
200 if let Some(scope) = self.scope.async_disposable() {
201 scope.dispose_async()
202 } else {
203 match self.scope.dispose_scope() {
204 Ok(()) => Task::from_result(()),
205 Err(error) => Task::from_exception(Rc::new(error)),
206 }
207 }
208 }
209}
210impl IDisposable for AsyncServiceScope {
211 fn dispose(&self) {
212 self.dispose().unwrap_or_else(|e| panic!("{e}"));
213 }
214}
215impl IAsyncDisposable for AsyncServiceScope {
216 fn dispose_async(&self) -> Task<()> {
217 self.dispose_async()
218 }
219}
220impl IServiceScope for AsyncServiceScope {
221 fn service_provider(&self) -> &ServiceProvider {
222 self.service_provider()
223 }
224 fn async_disposable(&self) -> Option<&dyn IAsyncDisposable> {
225 Some(self)
226 }
227 fn dispose_scope(&self) -> ServiceResult<()> {
228 self.dispose()
229 }
230}
231impl IServiceScope for ServiceScope {
232 fn async_disposable(&self) -> Option<&dyn IAsyncDisposable> {
233 Some(self)
234 }
235 fn dispose_scope(&self) -> ServiceResult<()> {
236 self.dispose()
237 }
238 fn service_provider(&self) -> &ServiceProvider {
239 &self.provider
240 }
241}
242impl ServiceScope {
243 pub fn service_provider(&self) -> &ServiceProvider {
244 &self.provider
245 }
246 pub fn dispose(&self) -> ServiceResult<()> {
247 self.provider.dispose()
248 }
249 pub fn dispose_async(&self) -> Task<()> {
250 self.provider.dispose_async()
251 }
252}
253impl IDisposable for ServiceScope {
254 fn dispose(&self) {
255 self.dispose().unwrap_or_else(|e| panic!("{e}"));
256 }
257}
258impl IAsyncDisposable for ServiceScope {
259 fn dispose_async(&self) -> Task<()> {
260 self.dispose_async()
261 }
262}
263
264struct ResolutionGuard(Rc<Root>);
265impl Drop for ResolutionGuard {
266 fn drop(&mut self) {
267 self.0.resolving.borrow_mut().pop();
268 }
269}
270
271impl ServiceProvider {
272 pub(crate) fn build(
273 descriptors: Vec<ServiceDescriptor>,
274 options: ServiceProviderOptions,
275 ) -> ServiceResult<Self> {
276 let scope = Rc::new(ScopeState::default());
277 let mut lookup: HashMap<_, Vec<_>> = HashMap::new();
278 for (i, descriptor) in descriptors.iter().enumerate() {
279 lookup
280 .entry(descriptor.identifier.clone())
281 .or_default()
282 .push(i);
283 }
284 let provider = Self {
285 root: Rc::new(Root {
286 descriptors,
287 lookup,
288 options,
289 scope: scope.clone(),
290 resolving: RefCell::new(Vec::new()),
291 validated: RefCell::new(HashSet::new()),
292 }),
293 scope,
294 };
295 if options.validate_on_build {
296 let mut done = HashSet::new();
297 let errors: Vec<_> = provider
298 .root
299 .descriptors
300 .iter()
301 .enumerate()
302 .filter_map(|(i, d)| {
303 provider
304 .validate(
305 i,
306 &d.identifier.service_key,
307 &mut Vec::new(),
308 &mut done,
309 false,
310 false,
311 )
312 .err()
313 })
314 .collect();
315 if !errors.is_empty() {
316 return Err(ServiceError::Validation(errors));
317 }
318 }
319 Ok(provider)
320 }
321 pub(crate) fn ensure_active(&self) -> ServiceResult<()> {
322 if self.scope.disposed.get() || self.root.scope.disposed.get() {
323 Err(ServiceError::Disposed)
324 } else {
325 Ok(())
326 }
327 }
328 pub fn same_as(&self, other: &ServiceProvider) -> bool {
330 Rc::ptr_eq(&self.root, &other.root) && Rc::ptr_eq(&self.scope, &other.scope)
331 }
332 pub fn is_disposed(&self) -> bool {
333 self.ensure_active().is_err()
334 }
335 pub fn create_scope(&self) -> ServiceResult<ServiceScope> {
336 self.ensure_active()?;
337 Ok(ServiceScope {
338 provider: Self {
339 root: self.root.clone(),
340 scope: Rc::new(ScopeState::default()),
341 },
342 })
343 }
344 pub fn create_async_scope(&self) -> ServiceResult<AsyncServiceScope> {
345 Ok(AsyncServiceScope::new(Rc::new(self.create_scope()?)))
346 }
347 pub fn get_service<S: ?Sized + 'static>(&self) -> ServiceResult<Option<Rc<S>>> {
348 ServiceProviderServiceExtensions::get_service(self)
349 }
350 pub fn get_required_service<S: ?Sized + 'static>(&self) -> ServiceResult<Rc<S>> {
351 ServiceProviderServiceExtensions::get_required_service(self)
352 }
353 pub fn get_services<S: ?Sized + 'static>(&self) -> ServiceResult<Vec<Rc<S>>> {
354 ServiceProviderServiceExtensions::get_services(self)
355 }
356 pub fn get_keyed_service<S: ?Sized + 'static>(
357 &self,
358 key: Option<&ServiceKey>,
359 ) -> ServiceResult<Option<Rc<S>>> {
360 ServiceProviderServiceExtensions::get_keyed_service(self, key)
361 }
362 pub fn get_required_keyed_service<S: ?Sized + 'static>(
363 &self,
364 key: Option<&ServiceKey>,
365 ) -> ServiceResult<Rc<S>> {
366 ServiceProviderServiceExtensions::get_required_keyed_service(self, key)
367 }
368 pub fn get_keyed_services<S: ?Sized + 'static>(
369 &self,
370 key: Option<&ServiceKey>,
371 ) -> ServiceResult<Vec<Rc<S>>> {
372 ServiceProviderServiceExtensions::get_keyed_services(self, key)
373 }
374 fn is_builtin(service_type: ServiceType) -> bool {
375 [
376 ServiceType::of::<dyn IServiceProvider>(),
377 ServiceType::of::<dyn IKeyedServiceProvider>(),
378 ServiceType::of::<dyn IServiceScopeFactory>(),
379 ServiceType::of::<dyn IServiceProviderIsService>(),
380 ServiceType::of::<dyn IServiceProviderIsKeyedService>(),
381 ]
382 .contains(&service_type)
383 }
384 fn builtin(&self, id: &ServiceIdentifier) -> Option<ErasedService> {
385 if id.service_key.is_some() {
386 return None;
387 }
388 let t = id.service_type;
389 fn cached<T: ?Sized + 'static>(
390 slot: &RefCell<Option<Weak<T>>>,
391 create: impl FnOnce() -> Rc<T>,
392 ) -> ErasedService {
393 if let Some(value) = slot.borrow().as_ref().and_then(Weak::upgrade) {
394 return erase_service(value);
395 }
396 let value = create();
397 *slot.borrow_mut() = Some(Rc::downgrade(&value));
398 erase_service(value)
399 }
400 if t == ServiceType::of::<dyn IServiceProvider>() {
401 return Some(cached(&self.scope.provider, || Rc::new(self.clone())));
402 }
403 if t == ServiceType::of::<dyn IKeyedServiceProvider>() {
404 return Some(cached(&self.scope.keyed_provider, || Rc::new(self.clone())));
405 }
406 let root = Self {
407 root: self.root.clone(),
408 scope: self.root.scope.clone(),
409 };
410 if t == ServiceType::of::<dyn IServiceScopeFactory>() {
411 return Some(cached(&self.root.scope.scope_factory, || Rc::new(root)));
412 }
413 if t == ServiceType::of::<dyn IServiceProviderIsService>() {
414 return Some(cached(&self.root.scope.is_service, || Rc::new(root)));
415 }
416 if t == ServiceType::of::<dyn IServiceProviderIsKeyedService>() {
417 return Some(cached(&self.root.scope.is_keyed_service, || Rc::new(root)));
418 }
419 None
420 }
421 fn matching(&self, id: &ServiceIdentifier, all: bool) -> ServiceResult<Vec<CacheKey>> {
422 if id.service_key.as_ref().is_some_and(ServiceKey::is_any) {
423 if !all {
424 return Err(ServiceError::AnyKeySingleResolution);
425 }
426 return Ok(self
427 .root
428 .descriptors
429 .iter()
430 .enumerate()
431 .filter(|(_, d)| {
432 d.service_type() == id.service_type
433 && d.service_key().is_some_and(|k| !k.is_any())
434 })
435 .map(|(index, d)| CacheKey {
436 index,
437 key: d.identifier.service_key.clone(),
438 })
439 .collect());
440 }
441 if let Some(indices) = self.root.lookup.get(id) {
442 return Ok(if all {
443 indices
444 .iter()
445 .map(|&index| CacheKey {
446 index,
447 key: id.service_key.clone(),
448 })
449 .collect()
450 } else {
451 vec![CacheKey {
452 index: *indices.last().unwrap(),
453 key: id.service_key.clone(),
454 }]
455 });
456 }
457 if !all && id.service_key.is_some() {
459 let any = ServiceIdentifier {
460 service_type: id.service_type,
461 service_key: Some(ServiceKey::ANY),
462 };
463 if let Some(indices) = self.root.lookup.get(&any) {
464 return Ok(vec![CacheKey {
465 index: *indices.last().unwrap(),
466 key: id.service_key.clone(),
467 }]);
468 }
469 }
470 Ok(Vec::new())
471 }
472 fn validate(
477 &self,
478 index: usize,
479 key: &Option<ServiceKey>,
480 path: &mut Vec<CacheKey>,
481 done: &mut HashSet<(CacheKey, bool, bool)>,
482 singleton: bool,
483 root_resolution: bool,
484 ) -> ServiceResult<()> {
485 let d = &self.root.descriptors[index];
486 let id = ServiceIdentifier {
487 service_type: d.service_type(),
488 service_key: key.clone(),
489 };
490 if self.root.options.validate_scopes && d.lifetime == ServiceLifetime::Scoped {
491 if singleton {
492 return Err(ServiceError::ScopedInSingleton(id));
493 }
494 if root_resolution {
495 return Err(ServiceError::ScopedFromRoot(id));
496 }
497 }
498 let cache_key = CacheKey {
499 index,
500 key: key.clone(),
501 };
502 if done.contains(&(cache_key.clone(), singleton, root_resolution)) {
504 return Ok(());
505 }
506 if path.contains(&cache_key) {
507 let mut ids: Vec<_> = path
508 .iter()
509 .map(|k| ServiceIdentifier {
510 service_type: self.root.descriptors[k.index].service_type(),
511 service_key: k.key.clone(),
512 })
513 .collect();
514 ids.push(id);
515 return Err(ServiceError::CircularDependency(ids));
516 }
517 let memo = (cache_key.clone(), singleton, root_resolution);
518 path.push(cache_key);
519 let singleton = singleton || d.lifetime == ServiceLifetime::Singleton;
520 for dependency in &d.dependencies {
521 let id = dependency.identifier_for(key);
522 if id.service_key.is_none() && Self::is_builtin(id.service_type) {
523 continue;
524 }
525 let matches = if dependency.kind == DependencyKind::Enumerable
526 && self.enumerable_override(&id).is_some()
527 {
528 vec![self.enumerable_override(&id).expect("enumerable override")]
529 } else if dependency.lookup_mode == ServiceKeyLookupMode::InheritKey
530 && key.as_ref().is_some_and(ServiceKey::is_any)
531 && dependency.kind != DependencyKind::Enumerable
532 {
533 self.root
534 .lookup
535 .get(&id)
536 .and_then(|indices| indices.last())
537 .map(|&index| {
538 vec![CacheKey {
539 index,
540 key: key.clone(),
541 }]
542 })
543 .unwrap_or_default()
544 } else {
545 self.matching(&id, dependency.kind == DependencyKind::Enumerable)?
546 };
547 if matches.is_empty() && dependency.kind == DependencyKind::Required {
548 return Err(ServiceError::MissingService(id));
549 }
550 for child in matches {
551 self.validate(
552 child.index,
553 &child.key,
554 path,
555 done,
556 singleton,
557 root_resolution,
558 )?;
559 }
560 }
561 path.pop();
562 done.insert(memo);
563 Ok(())
564 }
565 fn enumerable_override(&self, id: &ServiceIdentifier) -> Option<CacheKey> {
566 self.root
567 .descriptors
568 .iter()
569 .enumerate()
570 .rev()
571 .find_map(|(index, d)| {
572 (d.enumerable
573 .as_ref()
574 .is_some_and(|(element, _)| *element == id.service_type)
575 && d.service_key() == id.service_key.as_ref())
576 .then(|| CacheKey {
577 index,
578 key: id.service_key.clone(),
579 })
580 })
581 }
582 fn resolve(&self, key: CacheKey) -> ServiceResult<ErasedService> {
583 self.ensure_active()?;
584 let d = &self.root.descriptors[key.index];
585 let provider = if d.lifetime == ServiceLifetime::Singleton {
586 Self {
587 root: self.root.clone(),
588 scope: self.root.scope.clone(),
589 }
590 } else {
591 self.clone()
592 };
593 let validation_key = (key.clone(), Rc::ptr_eq(&self.scope, &self.root.scope));
594 if !self.root.validated.borrow().contains(&validation_key) {
595 self.validate(
596 key.index,
597 &key.key,
598 &mut Vec::new(),
599 &mut HashSet::new(),
600 false,
601 validation_key.1,
602 )?;
603 let mut validated = self.root.validated.borrow_mut();
606 if validated.len() >= MAX_VALIDATED {
607 validated.clear();
608 }
609 validated.insert(validation_key);
610 }
611 if d.lifetime != ServiceLifetime::Transient {
612 if let Some(value) = provider.scope.cache.borrow().get(&key) {
613 return Ok(value.clone());
614 }
615 }
616 let context = (key.clone(), Rc::as_ptr(&provider.scope) as usize);
617 if self.root.resolving.borrow().contains(&context) {
618 let mut ids: Vec<_> = self
619 .root
620 .resolving
621 .borrow()
622 .iter()
623 .map(|(k, _)| ServiceIdentifier {
624 service_type: self.root.descriptors[k.index].service_type(),
625 service_key: k.key.clone(),
626 })
627 .collect();
628 ids.push(ServiceIdentifier {
629 service_type: d.service_type(),
630 service_key: key.key.clone(),
631 });
632 return Err(ServiceError::CircularDependency(ids));
633 }
634 self.root.resolving.borrow_mut().push(context);
635 let _guard = ResolutionGuard(self.root.clone());
636 let value = (d.factory)(&provider, key.key.as_ref())?;
637 if d.dispose.is_some() || d.dispose_async.is_some() {
638 let captured = Captured {
639 value: value.clone(),
640 dispose: d.dispose.clone(),
641 dispose_async: d.dispose_async.clone(),
642 };
643 if provider.is_disposed() {
644 if let Some(dispose) = &captured.dispose {
646 dispose(&captured.value);
647 } else if let Some(dispose) = &captured.dispose_async {
648 drop(dispose(&captured.value));
650 }
651 return Err(ServiceError::Disposed);
652 }
653 provider.scope.disposables.borrow_mut().push(captured);
654 }
655 provider.ensure_active()?;
656 if d.lifetime != ServiceLifetime::Transient {
657 provider.scope.cache.borrow_mut().insert(key, value.clone());
658 }
659 Ok(value)
660 }
661 pub fn dispose(&self) -> ServiceResult<()> {
664 if self.scope.disposed.get() {
665 return Ok(());
666 }
667 if self
668 .scope
669 .disposables
670 .borrow()
671 .iter()
672 .any(|d| d.dispose.is_none() && d.dispose_async.is_some())
673 {
674 return Err(ServiceError::AsyncDisposalRequired);
675 }
676 self.scope.disposed.set(true);
677 let disposables = std::mem::take(&mut *self.scope.disposables.borrow_mut());
678 let cache = std::mem::take(&mut *self.scope.cache.borrow_mut());
679 for captured in disposables.into_iter().rev() {
680 if let Some(dispose) = captured.dispose {
681 dispose(&captured.value);
682 }
683 }
684 drop(cache);
685 Ok(())
686 }
687 pub fn dispose_async(&self) -> Task<()> {
688 if self.scope.disposed.replace(true) {
689 return Task::from_result(());
690 }
691 let disposables = std::mem::take(&mut *self.scope.disposables.borrow_mut());
692 let cache = std::mem::take(&mut *self.scope.cache.borrow_mut());
693 Task::spawn_local(async move {
694 for captured in disposables.into_iter().rev() {
695 if let Some(dispose) = captured.dispose_async {
696 dispose(&captured.value).await?;
697 } else if let Some(dispose) = captured.dispose {
698 dispose(&captured.value);
699 }
700 }
701 drop(cache);
702 Ok(())
703 })
704 }
705}
706impl IServiceProvider for ServiceProvider {
707 fn ensure_active(&self) -> ServiceResult<()> {
708 self.ensure_active()
709 }
710 fn required_service_provider(&self) -> Option<&dyn ISupportRequiredService> {
711 Some(self)
712 }
713 fn disposable(&self) -> Option<&dyn IDisposable> {
714 Some(self)
715 }
716 fn get_service_erased(&self, id: &ServiceIdentifier) -> ServiceResult<Option<ErasedService>> {
717 self.ensure_active()?;
718 if let Some(value) = self.builtin(id) {
719 return Ok(Some(value));
720 }
721 self.matching(id, false)?
722 .into_iter()
723 .next()
724 .map(|key| self.resolve(key))
725 .transpose()
726 }
727 fn get_services_erased(&self, id: &ServiceIdentifier) -> ServiceResult<Vec<ErasedService>> {
728 self.ensure_active()?;
729 if let Some(key) = self.enumerable_override(id) {
730 let enumerate = self.root.descriptors[key.index]
731 .enumerable
732 .as_ref()
733 .expect("enumerable")
734 .1;
735 return Ok(enumerate(&self.resolve(key)?));
736 }
737 self.matching(id, true)?
738 .into_iter()
739 .map(|key| self.resolve(key))
740 .collect()
741 }
742}
743impl IKeyedServiceProvider for ServiceProvider {}
744impl IServiceProviderIsService for ServiceProvider {
745 fn is_service(&self, service_type: ServiceType) -> bool {
746 self.is_keyed_service(service_type, None)
747 }
748}
749impl IServiceProviderIsKeyedService for ServiceProvider {
750 fn is_keyed_service(&self, service_type: ServiceType, key: Option<&ServiceKey>) -> bool {
751 (key.is_none() && Self::is_builtin(service_type))
752 || self.root.lookup.contains_key(&ServiceIdentifier {
753 service_type,
754 service_key: key.cloned(),
755 })
756 || (key.is_some()
757 && self.root.lookup.contains_key(&ServiceIdentifier {
758 service_type,
759 service_key: Some(ServiceKey::ANY),
760 }))
761 }
762}
763impl IServiceScopeFactory for ServiceProvider {
764 fn create_scope(&self) -> ServiceResult<ServiceScope> {
765 self.create_scope()
766 }
767}
768impl IDisposable for ServiceProvider {
771 fn dispose(&self) {
772 self.dispose().unwrap_or_else(|e| panic!("{e}"));
773 }
774}
775impl IAsyncDisposable for ServiceProvider {
776 fn dispose_async(&self) -> Task<()> {
777 self.dispose_async()
778 }
779}