1use crate::cache::{AnyService, LazyCache};
2use crate::entry::{
3 AsyncServiceFactory, IServiceResolver, ServiceEntry, ServiceFactory, ServiceLifetime,
4 ServiceStore,
5};
6use crate::error::RdiError;
7use crate::scope::ScopeFactory;
8use crate::validation::ValidationResolver;
9use std::any::{Any, TypeId};
10use std::cell::RefCell;
11use std::collections::HashMap;
12use std::panic::AssertUnwindSafe;
13use std::sync::{Arc, Mutex, OnceLock, RwLock, Weak};
14
15thread_local! {
16 static RESOLVING: RefCell<Vec<(usize, &'static str)>> = const { RefCell::new(Vec::new()) };
18}
19
20struct ResolveGuard;
21
22impl Drop for ResolveGuard {
23 fn drop(&mut self) {
24 RESOLVING.with(|stack| {
25 stack.borrow_mut().pop();
26 });
27 }
28}
29
30fn enter_resolve(cache_key: usize, type_name: &'static str) -> Result<ResolveGuard, RdiError> {
31 RESOLVING.with(|stack| {
32 let mut s = stack.borrow_mut();
33 if s.iter().any(|(k, _)| *k == cache_key) {
34 let mut chain: Vec<&str> = s.iter().map(|(_, n)| *n).collect();
35 chain.push(type_name);
36 return Err(RdiError::CircularDependency(chain.join(" -> ")));
37 }
38 s.push((cache_key, type_name));
39 Ok(ResolveGuard)
40 })
41}
42
43pub struct ServiceProvider {
44 store: Arc<ServiceStore>,
46 type_map: Arc<HashMap<&'static str, TypeId>>,
49 singleton_cache: Arc<LazyCache>,
53 root_scoped_cache: LazyCache,
61 pub(crate) named: Arc<RwLock<HashMap<String, Arc<dyn Any + Send + Sync>>>>,
66 self_weak: OnceLock<Weak<ServiceProvider>>,
71 disposables: Mutex<Vec<Box<dyn FnOnce() + Send>>>,
75}
76
77impl ServiceProvider {
78 pub(crate) fn new(store: ServiceStore) -> Result<Arc<Self>, RdiError> {
79 if let Some(entry) = store
81 .values()
82 .flat_map(|entries| entries.iter())
83 .find(|e| e.async_factory.is_some())
84 {
85 return Err(RdiError::AsyncServiceRequiresBuildAsync {
86 service: entry.type_name.to_string(),
87 });
88 }
89
90 let mut type_map = HashMap::new();
92 for (&tid, entries) in &store {
93 if let Some(e) = entries.first() {
94 type_map.entry(e.type_name).or_insert(tid);
95 }
96 }
97
98 let singleton_cache = Arc::new(LazyCache::new());
100 Self::validate_dependencies(&store, &singleton_cache)?;
101
102 let sp_arc = Arc::new(Self {
104 store: Arc::new(store),
105 type_map: Arc::new(type_map),
106 singleton_cache,
107 root_scoped_cache: LazyCache::new(),
108 named: Arc::new(RwLock::new(HashMap::new())),
109 self_weak: OnceLock::new(),
110 disposables: Mutex::new(Vec::new()),
111 });
112 sp_arc
113 .self_weak
114 .get_or_init(|| Arc::downgrade(&sp_arc));
115
116 Self::init_sync_singletons(&sp_arc);
117 Ok(sp_arc)
118 }
119
120 fn init_sync_singletons(sp_arc: &Arc<Self>) {
125 let singleton_entries: Vec<(usize, ServiceFactory)> = sp_arc
126 .store
127 .values()
128 .flat_map(|entries| entries.iter())
129 .filter(|e| e.lifetime == ServiceLifetime::Singleton && e.async_factory.is_none())
130 .map(|e| (e.cache_key, e.factory.clone()))
131 .collect();
132
133 for (ck, factory) in &singleton_entries {
134 let resolver = sp_arc.as_ref() as &dyn IServiceResolver;
135 let factory = factory.clone();
136 sp_arc
137 .singleton_cache
138 .get_or_init_with(*ck, move || factory(resolver));
139 }
140 }
141
142 pub(crate) async fn new_async(
151 store: ServiceStore,
152 ) -> Result<Arc<Self>, RdiError> {
153 let mut type_map = HashMap::new();
155 for (&tid, entries) in &store {
156 if let Some(e) = entries.first() {
157 type_map.entry(e.type_name).or_insert(tid);
158 }
159 }
160
161 let singleton_cache = Arc::new(LazyCache::new());
163 Self::validate_dependencies(&store, &singleton_cache)?;
164
165 let sp_arc = Arc::new(Self {
167 store: Arc::new(store),
168 type_map: Arc::new(type_map),
169 singleton_cache,
170 root_scoped_cache: LazyCache::new(),
171 named: Arc::new(RwLock::new(HashMap::new())),
172 self_weak: OnceLock::new(),
173 disposables: Mutex::new(Vec::new()),
174 });
175 sp_arc
176 .self_weak
177 .get_or_init(|| Arc::downgrade(&sp_arc));
178
179 Self::init_sync_singletons(&sp_arc);
180
181 let async_singletons: Vec<(usize, AsyncServiceFactory)> = sp_arc
183 .store
184 .values()
185 .flat_map(|entries| entries.iter())
186 .filter(|e| e.lifetime == ServiceLifetime::Singleton && e.async_factory.is_some())
187 .map(|e| (e.cache_key, e.async_factory.clone().unwrap()))
188 .collect();
189
190 for (ck, async_factory) in async_singletons {
191 let result = async_factory(Arc::clone(&sp_arc)).await;
192 sp_arc.singleton_cache.get_or_init_with(ck, || result);
193 }
194
195 Ok(sp_arc)
196 }
197
198 pub(crate) fn new_scope(parent: &Arc<Self>) -> Arc<Self> {
208 let sp = Self {
209 store: Arc::clone(&parent.store),
210 type_map: Arc::clone(&parent.type_map),
211 singleton_cache: Arc::clone(&parent.singleton_cache),
212 root_scoped_cache: LazyCache::new(),
213 named: Arc::clone(&parent.named),
214 self_weak: OnceLock::new(),
215 disposables: Mutex::new(Vec::new()),
216 };
217 let arc = Arc::new(sp);
218 let this: &Self = &arc;
219 this.self_weak.get_or_init(|| Arc::downgrade(&arc));
220 arc
221 }
222
223 pub fn register_disposable(&self, cleanup: Box<dyn FnOnce() + Send>) {
230 self.disposables.lock().unwrap().push(cleanup);
231 }
232
233 pub(crate) fn dispose_scoped(&self) {
240 let to_run: Vec<Box<dyn FnOnce() + Send>> = {
241 let mut guard = self.disposables.lock().unwrap();
242 std::mem::take(&mut *guard)
243 };
244 for cleanup in to_run {
245 cleanup();
246 }
247 }
248
249 fn validate_dependencies(store: &ServiceStore, cache: &LazyCache) -> Result<(), RdiError> {
253 let type_names: HashMap<TypeId, &'static str> = store
255 .iter()
256 .map(|(&tid, entries)| {
257 let name = entries.first().map(|e| e.type_name).unwrap_or("<unknown>");
258 (tid, name)
259 })
260 .collect();
261
262 for entries in store.values() {
266 for entry in entries {
267 if entry.lifetime == ServiceLifetime::Singleton && entry.async_factory.is_none() {
268 let resolver = ValidationResolver::new(store, &type_names, cache);
269 let type_name = entry.type_name;
270 let key = entry.key.clone();
271
272 let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
273 match &key {
274 Some(k) => resolver.get_keyed_any(type_name, k),
275 None => resolver.get_any(type_name),
276 }
277 }));
278
279 if let Some(err) = resolver.take_error() {
280 return Err(err);
281 }
282
283 match result {
284 Ok(_) => {}
285 Err(panic_info) => {
286 return Err(RdiError::from_panic_payload(type_name, panic_info));
287 }
288 }
289 }
290 }
291 }
292
293 Ok(())
294 }
295
296 pub fn get<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, RdiError> {
303 let type_name = std::any::type_name::<T>();
304 match self.resolve_optional::<T>() {
305 Ok(Some(v)) => Ok(v),
306 Ok(None) => Err(RdiError::not_found(type_name, None)),
307 Err(e) => Err(e),
308 }
309 }
310
311 pub fn get_optional<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>> {
313 self.resolve_optional::<T>().ok().flatten()
314 }
315
316 pub async fn get_async<T: ?Sized + Send + Sync + 'static>(
322 &self,
323 ) -> Result<Arc<T>, RdiError> {
324 let type_name = std::any::type_name::<T>();
325 let tid = TypeId::of::<T>();
326 let entry = self
327 .store
328 .get(&tid)
329 .and_then(|entries| entries.iter().find(|e| e.key.is_none()))
330 .ok_or_else(|| RdiError::not_found(type_name, None))?;
331
332 if entry.lifetime == ServiceLifetime::Singleton {
333 return self.get::<T>();
334 }
335
336 match self.resolve_async_any(entry, type_name).await? {
337 Some(arc_any) => Self::extract(arc_any).ok_or_else(|| RdiError::not_found(type_name, None)),
338 None => self.get::<T>(),
339 }
340 }
341
342 pub async fn get_keyed_async<T: ?Sized + Send + Sync + 'static>(
344 &self,
345 key: &str,
346 ) -> Result<Arc<T>, RdiError> {
347 let type_name = std::any::type_name::<T>();
348 let tid = TypeId::of::<T>();
349 let entry = self
350 .store
351 .get(&tid)
352 .and_then(|entries| entries.iter().find(|e| e.key.as_deref() == Some(key)))
353 .ok_or_else(|| RdiError::keyed_not_found(type_name, key, None))?;
354
355 if entry.lifetime == ServiceLifetime::Singleton {
356 return self.get_keyed::<T>(key);
357 }
358
359 match self.resolve_async_any(entry, type_name).await? {
360 Some(arc_any) => {
361 Self::extract(arc_any).ok_or_else(|| RdiError::keyed_not_found(type_name, key, None))
362 }
363 None => self.get_keyed::<T>(key),
364 }
365 }
366
367 async fn resolve_async_any(
370 &self,
371 entry: &ServiceEntry,
372 type_name: &'static str,
373 ) -> Result<Option<AnyService>, RdiError> {
374 match entry.lifetime {
375 ServiceLifetime::Scoped => {
376 let async_factory = entry
377 .async_factory
378 .clone()
379 .ok_or_else(|| RdiError::not_found(type_name, None))?;
380 let provider_arc = self.provider_arc().ok_or_else(|| RdiError::FactoryPanic {
381 service: type_name.to_string(),
382 payload: "provider_arc() returned None for async resolution".into(),
383 })?;
384 self.root_scoped_cache
385 .get_or_init_with_async(entry.cache_key, || {
386 Self::run_async_factory_safely(type_name, async_factory, provider_arc)
387 })
388 .await
389 .map(Some)
390 }
391 ServiceLifetime::Transient => {
392 if let Some(async_factory) = entry.async_factory.clone() {
393 let provider_arc = self.provider_arc().ok_or_else(|| RdiError::FactoryPanic {
394 service: type_name.to_string(),
395 payload: "provider_arc() returned None for async resolution".into(),
396 })?;
397 Self::run_async_factory_safely(type_name, async_factory, provider_arc)
398 .await
399 .map(Some)
400 } else {
401 Ok(None)
402 }
403 }
404 _ => Ok(None),
405 }
406 }
407
408 async fn run_async_factory_safely(
413 type_name: &'static str,
414 async_factory: AsyncServiceFactory,
415 provider_arc: Arc<ServiceProvider>,
416 ) -> Result<AnyService, RdiError> {
417 let fut = async_factory(provider_arc);
418 match futures::FutureExt::catch_unwind(AssertUnwindSafe(fut)).await {
419 Ok(arc_any) => Ok(arc_any),
420 Err(payload) => Err(RdiError::from_panic_payload(type_name, payload)),
421 }
422 }
423
424 pub fn get_keyed<T: ?Sized + Send + Sync + 'static>(&self, key: &str) -> Result<Arc<T>, RdiError> {
427 let type_name = std::any::type_name::<T>();
428 match self.resolve_keyed_optional::<T>(key) {
429 Ok(Some(v)) => Ok(v),
430 Ok(None) => Err(RdiError::keyed_not_found(type_name, key, None)),
431 Err(e) => Err(e),
432 }
433 }
434
435 pub fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError> {
438 let type_name = std::any::type_name::<T>();
439 let tid = TypeId::of::<T>();
440 let entry = self
441 .store
442 .get(&tid)
443 .and_then(|entries| entries.iter().find(|e| e.key.is_none()))
444 .ok_or_else(|| RdiError::not_found(type_name, None))?;
445 if entry.lifetime == ServiceLifetime::Singleton {
446 return Err(RdiError::OwnedNotSupported(type_name));
447 }
448 let arc_any = match std::panic::catch_unwind(AssertUnwindSafe(|| {
449 self.create_owned_any_by_entry(entry)
450 })) {
451 Ok(Some(v)) => v,
452 Ok(None) => return Err(RdiError::not_found(type_name, None)),
453 Err(payload) => return Err(RdiError::from_panic_payload(type_name, payload)),
454 };
455 let arc_t = Self::extract(arc_any).ok_or_else(|| RdiError::not_found(type_name, None))?;
456 Arc::try_unwrap(arc_t).map_err(|_| RdiError::OwnedNotSupported(type_name))
457 }
458
459 pub fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T> {
461 self.get_owned().ok()
462 }
463
464 pub fn get_keyed_owned<T: Send + Sync + 'static>(&self, key: &str) -> Result<T, RdiError> {
467 let type_name = std::any::type_name::<T>();
468 let tid = TypeId::of::<T>();
469 let entry = self
470 .store
471 .get(&tid)
472 .and_then(|entries| entries.iter().find(|e| e.key.as_deref() == Some(key)))
473 .ok_or_else(|| RdiError::keyed_not_found(type_name, key, None))?;
474 if entry.lifetime == ServiceLifetime::Singleton {
475 return Err(RdiError::OwnedNotSupported(type_name));
476 }
477 let arc_any = match std::panic::catch_unwind(AssertUnwindSafe(|| {
478 self.create_owned_any_by_entry(entry)
479 })) {
480 Ok(Some(v)) => v,
481 Ok(None) => return Err(RdiError::keyed_not_found(type_name, key, None)),
482 Err(payload) => return Err(RdiError::from_panic_payload(type_name, payload)),
483 };
484 let arc_t =
485 Self::extract(arc_any).ok_or_else(|| RdiError::keyed_not_found(type_name, key, None))?;
486 Arc::try_unwrap(arc_t).map_err(|_| RdiError::OwnedNotSupported(type_name))
487 }
488
489 pub fn try_get_keyed_owned<T: Send + Sync + 'static>(&self, key: &str) -> Option<T> {
491 self.get_keyed_owned(key).ok()
492 }
493
494 pub fn get_all<T: ?Sized + Send + Sync + 'static>(&self) -> Vec<Arc<T>> {
496 let tid = TypeId::of::<T>();
497 match self.store.get(&tid) {
498 Some(entries) => entries
499 .iter()
500 .filter_map(|e| {
501 let arc = self.get_any_by_entry(e)?;
502 Self::extract(arc)
503 })
504 .collect(),
505 None => Vec::new(),
506 }
507 }
508
509 pub fn scope(self: &Arc<Self>) -> crate::scope::Scope {
514 crate::scope::Scope::new(self.clone())
515 }
516
517 #[allow(dead_code)]
518 fn try_get<T: ?Sized + Send + Sync + 'static>(&self) -> Option<Arc<T>> {
519 self.resolve_optional::<T>().ok().flatten()
520 }
521
522 #[allow(dead_code)]
523 fn try_get_keyed<T: ?Sized + Send + Sync + 'static>(&self, key: &str) -> Option<Arc<T>> {
524 self.resolve_keyed_optional::<T>(key).ok().flatten()
525 }
526
527 fn resolve_optional<T: ?Sized + Send + Sync + 'static>(
529 &self,
530 ) -> Result<Option<Arc<T>>, RdiError> {
531 let tid = TypeId::of::<T>();
532 if let Some(entry) = self
533 .store
534 .get(&tid)
535 .and_then(|entries| entries.iter().find(|e| e.key.is_none()))
536 {
537 let arc = self.resolve_entry_catching(entry)?;
538 return Ok(Self::extract(arc));
539 }
540 if tid == TypeId::of::<dyn ScopeFactory>() {
542 let Some(p) = self.provider_arc() else {
543 return Ok(None);
544 };
545 let sf: Arc<dyn ScopeFactory> = p;
546 return Ok(Self::extract(Arc::new(sf) as AnyService));
547 }
548 Ok(None)
549 }
550
551 fn resolve_keyed_optional<T: ?Sized + Send + Sync + 'static>(
552 &self,
553 key: &str,
554 ) -> Result<Option<Arc<T>>, RdiError> {
555 let tid = TypeId::of::<T>();
556 let Some(entry) = self
557 .store
558 .get(&tid)
559 .and_then(|entries| entries.iter().find(|e| e.key.as_deref() == Some(key)))
560 else {
561 return Ok(None);
562 };
563 let arc = self.resolve_entry_catching(entry)?;
564 Ok(Self::extract(arc))
565 }
566
567 pub(crate) fn resolve_entry_catching(&self, entry: &ServiceEntry) -> Result<AnyService, RdiError> {
568 match std::panic::catch_unwind(AssertUnwindSafe(|| self.get_any_by_entry(entry))) {
569 Ok(Some(v)) => Ok(v),
570 Ok(None) => Err(RdiError::not_found(entry.type_name, None)),
571 Err(payload) => Err(RdiError::from_panic_payload(entry.type_name, payload)),
572 }
573 }
574
575 pub(crate) fn get_any_by_entry(&self, entry: &ServiceEntry) -> Option<AnyService> {
576 let _guard = match enter_resolve(entry.cache_key, entry.type_name) {
577 Ok(g) => g,
578 Err(e) => std::panic::panic_any(e),
579 };
580 match entry.lifetime {
581 ServiceLifetime::Singleton => {
582 let factory = entry.factory.clone();
587 let resolver = self as &dyn IServiceResolver;
588 Some(self.singleton_cache.get_or_init_with(entry.cache_key, move || {
589 factory(resolver)
590 }))
591 }
592 ServiceLifetime::Scoped => {
593 let factory = entry.factory.clone();
596 let resolver = self as &dyn IServiceResolver;
597 Some(self.root_scoped_cache.get_or_init_with(entry.cache_key, move || {
598 factory(resolver)
599 }))
600 }
601 ServiceLifetime::Transient => Some((entry.factory)(self)),
602 }
603 }
604
605 pub(crate) fn create_owned_any_by_entry(&self, entry: &ServiceEntry) -> Option<AnyService> {
614 match entry.lifetime {
615 ServiceLifetime::Singleton => None,
616 ServiceLifetime::Scoped | ServiceLifetime::Transient => {
617 let _guard = match enter_resolve(entry.cache_key, entry.type_name) {
618 Ok(g) => g,
619 Err(e) => std::panic::panic_any(e),
620 };
621 Some((entry.factory)(self as &dyn IServiceResolver))
622 }
623 }
624 }
625
626 pub(crate) fn extract<T: ?Sized + Send + Sync + 'static>(
629 arc: Arc<dyn Any + Send + Sync>,
630 ) -> Option<Arc<T>> {
631 let double: Arc<Arc<T>> = arc.downcast::<Arc<T>>().ok()?;
632 Some(Arc::clone(&*double))
633 }
634
635 pub(crate) fn entry_by_str(&self, type_name: &str, variant: &str) -> Option<&ServiceEntry> {
637 let tid = self.type_map.get(type_name)?;
638 self.store
639 .get(tid)?
640 .iter()
641 .find(|e| e.key.as_deref() == Some(variant))
642 }
643
644 pub fn get_named<T: Send + Sync + 'static>(&self, name: &str) -> Option<Arc<T>> {
646 self.named
647 .read()
648 .unwrap()
649 .get(name)?
650 .clone()
651 .downcast::<T>()
652 .ok()
653 }
654
655 pub fn get_named_any(&self, name: &str) -> Option<Arc<dyn Any + Send + Sync>> {
657 self.named.read().unwrap().get(name).cloned()
658 }
659
660 pub fn register_named<T: Send + Sync + 'static>(&self, name: &str, service: Arc<T>) {
662 self.named
663 .write()
664 .unwrap()
665 .insert(name.to_string(), service);
666 }
667
668 pub fn remove_named(&self, name: &str) {
670 self.named.write().unwrap().remove(name);
671 }
672
673 pub fn rdi_register_named(&self, name: &str, service: Arc<dyn Any + Send + Sync>) {
675 self.named
676 .write()
677 .unwrap()
678 .insert(name.to_string(), service);
679 }
680
681 pub fn rdi_remove_named(&self, name: &str) {
683 self.named.write().unwrap().remove(name);
684 }
685}
686
687impl ScopeFactory for ServiceProvider {
688 fn create_scope(&self) -> crate::scope::Scope {
689 self.self_weak
691 .get()
692 .and_then(|w| w.upgrade())
693 .map(crate::scope::Scope::new)
694 .expect("ScopeFactory::create_scope: ServiceProvider self_weak not initialized")
695 }
696}
697
698impl IServiceResolver for ServiceProvider {
699 fn get_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
700 let tid = self.type_map.get(key)?;
701 let entry = self.store.get(tid)?.iter().find(|e| e.key.is_none())?;
702 self.get_any_by_entry(entry)
703 }
704 fn get_keyed_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>> {
705 let entry = self.entry_by_str(key, variant)?;
706 self.get_any_by_entry(entry)
707 }
708 fn get_by_type_id(&self, tid: TypeId) -> Option<Arc<dyn Any + Send + Sync>> {
709 if let Some(entry) = self.store.get(&tid)?.iter().find(|e| e.key.is_none()) {
710 return self.get_any_by_entry(entry);
711 }
712 if tid == TypeId::of::<dyn ScopeFactory>() {
713 let p = self.provider_arc()?;
714 let sf: Arc<dyn ScopeFactory> = p;
715 return Some(Arc::new(sf) as AnyService);
716 }
717 None
718 }
719 fn get_keyed_by_type_id(
720 &self,
721 tid: TypeId,
722 key: &str,
723 ) -> Option<Arc<dyn Any + Send + Sync>> {
724 let entry = self
725 .store
726 .get(&tid)?
727 .iter()
728 .find(|e| e.key.as_deref() == Some(key))?;
729 self.get_any_by_entry(entry)
730 }
731 fn get_all_any(&self, key: &str) -> Vec<Arc<dyn Any + Send + Sync>> {
732 let tid = match self.type_map.get(key) {
735 Some(t) => t,
736 None => return Vec::new(),
737 };
738 match self.store.get(tid) {
739 Some(entries) => entries
740 .iter()
741 .filter_map(|e| self.get_any_by_entry(e))
742 .collect(),
743 None => Vec::new(),
744 }
745 }
746 fn get_owned_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
747 let tid = self.type_map.get(key)?;
748 let entry = self.store.get(tid)?.iter().find(|e| e.key.is_none())?;
749 self.create_owned_any_by_entry(entry)
750 }
751 fn get_keyed_owned_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>> {
752 let entry = self.entry_by_str(key, variant)?;
753 self.create_owned_any_by_entry(entry)
754 }
755 fn provider_arc(&self) -> Option<Arc<ServiceProvider>> {
756 self.self_weak.get().and_then(|w| w.upgrade())
757 }
758}
759
760#[cfg(test)]
761mod tests {
762 use crate::collection::ServiceCollection;
763 use std::sync::Arc;
764
765 #[derive(Debug, PartialEq)]
766 struct Calc(i32);
767 #[test]
768 fn optional_missing() {
769 let p = ServiceCollection::new().build().unwrap();
770 assert!(p.get_optional::<i32>().is_none());
771 }
772 #[test]
773 fn all_basic() {
774 let p = ServiceCollection::new()
775 .keyed_singleton("a", |_| Arc::new(Calc(1)))
776 .keyed_singleton("b", |_| Arc::new(Calc(2)))
777 .build()
778 .unwrap();
779 assert_eq!(p.get_all::<Calc>().len(), 2);
780 }
781}