anthill_di/
dependency_context.rs

1#[cfg(feature = "async-mode")]
2use crate::constructors::ComponentFromAsyncClosure;
3#[cfg(feature = "async-mode")]
4use std::future::Future;
5
6use crate::{
7    Constructor,
8    ComponentFromConstructor,
9    types::{
10        TypeInfo,
11        DeleteComponentResult,
12    },
13    constructors::{
14        ComponentFromClosure,
15        ComponentFromInstance,
16    },
17};
18use std::marker::Unsize;
19use std::{
20    any::TypeId,
21    sync::Arc,
22};
23
24use crate::{
25    CoreContext,
26    LocalContext,
27    ServiceMappingBuilder,
28    types::{
29        BuildDependencyResult,
30        AddDependencyResult,
31        MapComponentResult,
32    },
33    LifeCycle,
34};
35
36#[derive(Debug, PartialEq, Clone)]
37pub (crate) enum DependencyContextId {
38    TypeId(TypeInfo),
39    Root,
40}
41
42/// Root di context, or child context (in ctor or closure)
43/// Main component. You work with it most of the time
44#[derive(Debug, Clone)]
45pub struct DependencyContext {
46    id: DependencyContextId,
47    core_context: Arc<CoreContext>,
48    pub (crate) local_context: Arc<LocalContext>,
49}
50
51impl DependencyContext {
52    /// Create new root empty context
53    pub fn new_root() -> Self {
54        Self {
55            id: DependencyContextId::Root,
56            core_context: Arc::new(Default::default()),
57            local_context: Arc::new(Default::default()),
58        }
59    }
60
61    #[inline(always)]
62    pub (crate) fn new_dependency(id: DependencyContextId, core_context: Arc<CoreContext>, local_context: Arc<LocalContext>) -> Self {
63        Self { id, core_context, local_context, }
64    }
65
66    /// Set saved local context
67    #[inline(always)]
68    pub fn set_context(&mut self, local_context: Arc<LocalContext>) { self.local_context = local_context }
69
70    /// Set new local context and return copy
71    #[inline(always)]
72    pub fn set_empty_context(&mut self) -> Arc<LocalContext> {
73        self.local_context = Arc::new(Default::default());
74        self.local_context.clone()
75    }
76
77    /// Get copy local context.
78    /// 
79    /// Save local context, before set_empty_context, if you need not to lose context dependent components
80    /// 
81    /// Then you can restore context with ```set_context```
82    #[inline(always)]
83    pub fn get_context(&self) -> Arc<LocalContext> { self.local_context.clone() }
84}
85
86#[cfg(feature = "async-mode")]
87impl DependencyContext {
88    /// Register component witch implement trait Constructor
89    /// 
90    /// Remember, lifetime required smart pointers wrapper:
91    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
92    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
93    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
94    /// 
95    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
96    ///# Example
97    ///---
98    /// From root context
99    /// ```ignore
100    /// struct SomeComponent {}
101    /// 
102    /// let root_context = DependencyContext::new_root();
103    /// root_context.register_type::<SomeComponent>(LifeCycle::Transient).await.unwrap();
104    /// ```
105    /// 
106    /// ---
107    /// 
108    /// From ctor context
109    /// ```ignore
110    /// struct SomeComponent {}
111    /// 
112    /// #[async_trait_with_sync::async_trait(Sync)]
113    /// impl Constructor for SomeOtherComponent {
114    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
115    ///         // unwrap or map error to BuildDependencyError
116    ///         ctx.register_type::<SomeComponent>(LifeCycle::Transient).await.unwrap();
117    ///         Ok(Self { })
118    ///     }
119    /// }
120    /// 
121    /// ```
122    #[inline(always)]
123    pub async fn register_type<TComponent: Constructor + Sync + Send + 'static>(&self, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
124        self.core_context.register::<TComponent>(Box::new(ComponentFromConstructor::<TComponent>::new()), life_cycle).await
125    }
126
127    /// Register component from async closure
128    /// 
129    /// Remember, lifetime required smart pointers wrapper:
130    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
131    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
132    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
133    /// 
134    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
135    ///# Example
136    ///---
137    /// From root context
138    /// ```ignore
139    /// struct SomeComponent {}
140    /// 
141    /// let root_context = DependencyContext::new_root();
142    /// root_context.register_closure(async |_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();
143    /// ```
144    /// 
145    /// ---
146    /// 
147    /// From ctor context
148    /// ```ignore
149    /// struct SomeComponent {}
150    /// 
151    /// #[async_trait_with_sync::async_trait(Sync)]
152    /// impl Constructor for SomeOtherComponent {
153    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
154    ///         // unwrap or map error to BuildDependencyError
155    ///         ctx.register_closure(async |_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();
156    ///         Ok(Self { })
157    ///     }
158    /// }
159    /// 
160    /// ```
161    #[inline(always)]
162    pub async fn register_async_closure<TComponent, TFuture, TClosure>(&self, closure: TClosure, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>>
163    where
164        TComponent: Sync + Send + 'static,
165        TFuture: Future<Output = BuildDependencyResult<TComponent>>,
166        TFuture: Sync + Send + 'static,
167        TClosure: Fn(DependencyContext) -> TFuture,
168        TClosure: Sync + Send + 'static,
169    {
170        self.core_context.register::<TComponent>(Box::new(ComponentFromAsyncClosure::<TComponent, TFuture, TClosure>::new(closure)), life_cycle).await
171    }
172
173    /// Register component from closure
174    /// 
175    /// Remember, lifetime required smart pointers wrapper:
176    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
177    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
178    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
179    /// 
180    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
181    ///# Example
182    ///---
183    /// From root context
184    /// ```ignore
185    /// struct SomeComponent {}
186    /// 
187    /// let root_context = DependencyContext::new_root();
188    /// root_context.register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();
189    /// ```
190    /// 
191    /// ---
192    /// 
193    /// From ctor context
194    /// ```ignore
195    /// struct SomeComponent {}
196    /// 
197    /// #[async_trait_with_sync::async_trait(Sync)]
198    /// impl Constructor for SomeOtherComponent {
199    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
200    ///         // unwrap or map error to BuildDependencyError
201    ///         ctx.register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).await.unwrap();
202    ///         Ok(Self { })
203    ///     }
204    /// }
205    /// 
206    /// ```
207    #[inline(always)]
208    pub async fn register_closure<TComponent: Sync + Send + 'static, TClosure: Fn(DependencyContext) -> BuildDependencyResult<TComponent> + Sync + Send + 'static>(&self, closure: TClosure, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
209        self.core_context.register::<TComponent>(Box::new(ComponentFromClosure::<TComponent>::new(Box::new(closure))), life_cycle).await
210    }
211
212    /// Register component instance as singleton
213    /// 
214    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
215    ///# Example
216    ///---
217    /// From root context
218    /// ```ignore
219    /// struct SomeComponent {}
220    /// 
221    /// let root_context = DependencyContext::new_root();
222    /// root_context.register_instance::<SomeComponent>(SomeComponent::new()).await.unwrap();
223    /// ```
224    /// 
225    /// ---
226    /// 
227    /// From ctor context
228    /// ```ignore
229    /// struct SomeComponent {}
230    /// 
231    /// #[async_trait_with_sync::async_trait(Sync)]
232    /// impl Constructor for SomeOtherComponent {
233    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
234    ///         // unwrap or map error to BuildDependencyError
235    ///         ctx.register_instance::<SomeComponent>(SomeComponent::new()).await.unwrap();
236    ///         Ok(Self { })
237    ///     }
238    /// }
239    /// 
240    /// ```
241    #[inline(always)]
242    pub async fn register_instance<TComponent: Sync + Send + 'static>(&self, instance: TComponent) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
243        self.core_context.register::<TComponent>(Box::new(ComponentFromInstance::new(instance)), LifeCycle::Singleton).await
244    }
245
246    /// Map component as service
247    ///# Example
248    ///---
249    /// From root context
250    /// ```ignore
251    /// struct SomeComponent {}
252    /// trait SomeService {}
253    /// 
254    /// let root_context = DependencyContext::new_root();
255    /// //...
256    /// 
257    /// // SomeComponent must be registered, or will be error
258    /// root_context.map_component::<SomeComponent, dyn SomeService>().await.unwrap();
259    /// ```
260    /// 
261    /// ---
262    /// 
263    /// From ctor context
264    /// ```ignore
265    /// struct SomeComponent {}
266    /// trait SomeService {}
267    /// 
268    /// #[async_trait_with_sync::async_trait(Sync)]
269    /// impl Constructor for SomeOtherComponent {
270    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
271    ///         // SomeComponent must be registered, or will be error
272    ///         // unwrap or map error to BuildDependencyError
273    ///         ctx.map_component::<SomeComponent, dyn SomeService>().await.unwrap();
274    ///         Ok(Self { })
275    ///     }
276    /// }
277    /// 
278    /// ```
279    #[inline(always)]
280    pub async fn map_component<TComponent: Sync + Send + 'static, TService: ?Sized + Sync + Send + 'static>(&self) -> MapComponentResult<Arc<CoreContext>> where TComponent: Unsize<TService> {
281        self.core_context.map_component::<TComponent, TService>().await
282    }
283
284    /// Resolve first component, mapped to service
285    /// ``` ignore
286    /// // You can resolve transient like:
287    /// ctx.resolve::<Box<dyn Service>>().await.unwrap()
288    /// ctx.resolve::<Box<Component>>().await.unwrap()
289    /// 
290    /// // You can resolve singleton like:
291    /// ctx.resolve::<Arc<dyn Service>>().await.unwrap()
292    /// ctx.resolve::<Arc<Component>>().await.unwrap()
293    /// 
294    /// // You can resolve context dependent like:
295    /// ctx.resolve::<Weak<dyn Service>>().await.unwrap()
296    /// ctx.resolve::<Weak<Component>>().await.unwrap()
297    /// 
298    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
299    /// ctx.resolve::<Weak<RwLock<dyn Service>>>().await.unwrap()
300    ///  
301    /// ```
302    ///# Example
303    ///---
304    /// From root context
305    /// ```ignore
306    /// trait SomeService {}
307    /// 
308    /// let root_context = DependencyContext::new_root();
309    /// let service: Box<dyn SomeTrait> = root_context.resolve::<Box<dyn SomeService>>().await.unwrap();
310    /// ```
311    /// 
312    /// ---
313    /// 
314    /// From ctor context
315    /// ```ignore
316    /// trait SomeService {}
317    /// 
318    /// #[async_trait_with_sync::async_trait(Sync)]
319    /// impl Constructor for SomeOtherComponent {
320    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
321    ///         // unwrap or map error to BuildDependencyError
322    ///         let service: Box<dyn SomeTrait> = ctx.resolve::<Box<dyn SomeService>>().await.unwrap();
323    ///         Ok(Self { })
324    ///     }
325    /// }
326    /// 
327    /// ```
328    #[inline(always)]
329    pub async fn resolve<'a, TService: Sync + Send + 'static>(&'a self) -> BuildDependencyResult<TService> {
330        self.core_context.resolve::<TService>(self.id.clone(), self.local_context.clone()).await
331    }
332
333    /// Resolve component with TypeId, mapped to service
334    /// That may be helpful in case, when you need current component, type is lost, but you can save TypeId as variable
335    /// ``` ignore
336    /// // You can resolve transient like:
337    /// ctx.resolve_by_type_id::<Box<dyn Service>>(TypeId::of::<Component>()).await.unwrap()
338    /// ctx.resolve_by_type_id::<Box<Component>>(TypeId::of::<Component>()).await.unwrap()
339    /// 
340    /// // You can resolve singleton like:
341    /// ctx.resolve_by_type_id::<Arc<dyn Service>>(TypeId::of::<Component>()).await.unwrap()
342    /// ctx.resolve_by_type_id::<Arc<Component>>(TypeId::of::<Component>()).await.unwrap()
343    /// 
344    /// // You can resolve context dependent like:
345    /// ctx.resolve_by_type_id::<Weak<dyn Service>>(TypeId::of::<Component>()).await.unwrap()
346    /// ctx.resolve_by_type_id::<Weak<Component>>(TypeId::of::<Component>()).await.unwrap()
347    /// 
348    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
349    /// ctx.resolve_by_type_id::<Weak<RwLock<dyn Service>>>(TypeId::of::<Component>()).await.unwrap()
350    ///  
351    /// ```
352    ///# Example
353    ///---
354    /// From root context
355    /// ```ignore
356    /// struct SomeComponent {}
357    /// trait SomeService {}
358    /// 
359    /// let root_context = DependencyContext::new_root();
360    /// let service: Box<dyn SomeTrait> = root_context.resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).await.unwrap();
361    /// ```
362    /// 
363    /// ---
364    /// 
365    /// From ctor context
366    /// ```ignore
367    /// struct SomeComponent {}
368    /// trait SomeService {}
369    /// 
370    /// #[async_trait_with_sync::async_trait(Sync)]
371    /// impl Constructor for SomeOtherComponent {
372    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
373    ///         // unwrap or map error to BuildDependencyError
374    ///         let service: Box<dyn SomeTrait> = ctx.resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).await.unwrap();
375    ///         Ok(Self { })
376    ///     }
377    /// }
378    /// 
379    /// ```
380    #[inline(always)]
381    pub async fn resolve_by_type_id<TService: Sync + Send + 'static>(&self, component_type_id: TypeId) -> BuildDependencyResult<TService> {
382        self.core_context.resolve_by_type_id::<TService>(component_type_id, self.id.clone(), self.local_context.clone()).await
383    }
384
385    /// Resolve all component, mapped to service
386    /// ``` ignore
387    /// // You can resolve transient like:
388    /// ctx.resolve_collection::<Box<dyn Service>>().await.unwrap()
389    /// ctx.resolve_collection::<Box<Component>>().await.unwrap()
390    /// 
391    /// // You can resolve singleton like:
392    /// ctx.resolve_collection::<Arc<dyn Service>>().await.unwrap()
393    /// ctx.resolve_collection::<Arc<Component>>().await.unwrap()
394    /// 
395    /// // You can resolve context dependent like:
396    /// ctx.resolve_collection::<Weak<dyn Service>>().await.unwrap()
397    /// ctx.resolve_collection::<Weak<Component>>().await.unwrap()
398    /// 
399    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
400    /// ctx.resolve_collection::<Weak<RwLock<dyn Service>>>().await.unwrap()
401    ///  
402    /// ```
403    ///# Example
404    ///---
405    /// From root context
406    /// ```ignore
407    /// trait SomeService {}
408    /// 
409    /// let root_context = DependencyContext::new_root();
410    /// let collection: Vec<Box<dyn SomeService>> = root_context.resolve_collection::<Box<dyn SomeService>>().await.unwrap();
411    /// ```
412    /// 
413    /// ---
414    /// 
415    /// From ctor context
416    /// ```ignore
417    /// trait SomeService {}
418    /// 
419    /// #[async_trait_with_sync::async_trait(Sync)]
420    /// impl Constructor for SomeOtherComponent {
421    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
422    ///         // unwrap or map error to BuildDependencyError
423    ///         let collection: Vec<Box<dyn SomeService>> = ctx.resolve_collection::<Box<dyn SomeService>>().await.unwrap();
424    ///         Ok(Self { })
425    ///     }
426    /// }
427    /// 
428    /// ```
429    #[inline(always)]
430    pub async fn resolve_collection<TService: Sync + Send + 'static>(&self) -> BuildDependencyResult<Vec<TService>> {
431        self.core_context.resolve_collection::<TService>(self.id.clone(), self.local_context.clone()).await
432    }
433
434    /// Delete component
435    ///# Example
436    ///---
437    /// From root context
438    /// ```ignore
439    /// struct SomeComponent {}
440    /// 
441    /// let root_context = DependencyContext::new_root();
442    /// root_context.delete_component::<SomeComponent>().await.unwrap();
443    /// ```
444    /// 
445    /// ---
446    /// 
447    /// From ctor context
448    /// ```ignore
449    /// struct SomeComponent {}
450    /// 
451    /// #[async_trait_with_sync::async_trait(Sync)]
452    /// impl Constructor for SomeOtherComponent {
453    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
454    ///         // unwrap or map error to BuildDependencyError
455    ///         ctx.delete_component::<SomeComponent>().await.unwrap();
456    ///         Ok(Self { })
457    ///     }
458    /// }
459    /// 
460    /// ```
461    #[inline(always)]
462    pub async fn delete_component<TComponent: 'static>(&self) -> DeleteComponentResult<()> {
463        self.core_context.delete_component::<TComponent>().await
464    }
465
466    /// Check service existence
467    /// ``` ignore
468    /// // You can check transient like:
469    /// ctx.is_service_exist::<Box<dyn Service>>().await.unwrap()
470    /// ctx.is_service_exist::<Box<Component>>().await.unwrap()
471    /// 
472    /// // You can check singleton like:
473    /// ctx.is_service_exist::<Arc<dyn Service>>().await.unwrap()
474    /// ctx.is_service_exist::<Arc<Component>>().await.unwrap()
475    /// 
476    /// // You can check context dependent like:
477    /// ctx.is_service_exist::<Weak<dyn Service>>().await.unwrap()
478    /// ctx.is_service_exist::<Weak<Component>>().await.unwrap()
479    /// 
480    /// // remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
481    /// ctx.is_service_exist::<Weak<RwLock<dyn Service>>>().await.unwrap()
482    ///  
483    /// ```
484    ///# Example
485    ///---
486    /// From root context
487    /// ```ignore
488    /// trait SomeService {}
489    /// 
490    /// let root_context = DependencyContext::new_root();
491    /// let is_exist: bool = root_context.is_service_exist::<Box<dyn SomeService>>().await;
492    /// ```
493    /// 
494    /// ---
495    /// 
496    /// From ctor context
497    /// ```ignore
498    /// trait SomeService {}
499    /// 
500    /// #[async_trait_with_sync::async_trait(Sync)]
501    /// impl Constructor for SomeOtherComponent {
502    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
503    ///         let is_exist: bool = ctx.is_service_exist::<Box<dyn SomeService>>().await;
504    ///         Ok(Self { })
505    ///     }
506    /// }
507    /// 
508    /// ```
509    #[inline(always)]
510    pub async fn is_service_exist<TService: 'static>(&self) -> bool {
511        self.core_context.is_service_exist(TypeId::of::<TService>()).await
512    }
513
514    /// Check service existence by type id
515    /// ``` ignore
516    /// // You can check transient like:
517    /// ctx.is_service_with_type_id_exist(TypeId::of::<Box<dyn Service>>()).await.unwrap()
518    /// ctx.is_service_with_type_id_exist(TypeId::of::<Box<Component>>()).await.unwrap()
519    /// 
520    /// // You can check singleton like:
521    /// ctx.is_service_with_type_id_exist(TypeId::of::<Arc<dyn Service>>()).await.unwrap()
522    /// ctx.is_service_with_type_id_exist(TypeId::of::<Arc<Component>>()).await.unwrap()
523    /// 
524    /// // You can check context dependent like:
525    /// ctx.is_service_with_type_id_exist(TypeId::of::<Weak<dyn Service>>()).await.unwrap()
526    /// ctx.is_service_with_type_id_exist(TypeId::of::<Weak<Component>>()).await.unwrap()
527    /// 
528    /// // remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
529    /// ctx.is_service_with_type_id_exist(TypeId::of::<Weak<RwLock<dyn Service>>>()).await.unwrap()
530    ///  
531    /// ```
532    ///# Example
533    ///---
534    /// From root context
535    /// ```ignore
536    /// trait SomeService {}
537    /// 
538    /// let root_context = DependencyContext::new_root();
539    /// let is_exist: bool = root_context.is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>()).await;
540    /// ```
541    /// 
542    /// ---
543    /// 
544    /// From ctor context
545    /// ```ignore
546    /// trait SomeService {}
547    /// 
548    /// #[async_trait_with_sync::async_trait(Sync)]
549    /// impl Constructor for SomeOtherComponent {
550    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
551    ///         let is_exist: bool = ctx.is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>()).await;
552    ///         Ok(Self { })
553    ///     }
554    /// }
555    /// 
556    /// ```
557    #[inline(always)]
558    pub async fn is_service_with_type_id_exist(&self, service_type_id: TypeId) -> bool {
559        self.core_context.is_service_exist(service_type_id).await
560    }
561
562    /// Check component existence
563    ///# Example
564    ///---
565    /// From root context
566    /// ```ignore
567    /// struct SomeComponent {}
568    /// 
569    /// let root_context = DependencyContext::new_root();
570    /// let is_exist: bool = root_context.is_component_exist::<SomeComponent>().await;
571    /// ```
572    /// 
573    /// ---
574    /// 
575    /// From ctor context
576    /// ```ignore
577    /// struct SomeComponent {}
578    /// 
579    /// #[async_trait_with_sync::async_trait(Sync)]
580    /// impl Constructor for SomeOtherComponent {
581    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
582    ///         let is_exist: bool = ctx.is_component_exist::<SomeComponent>().await;
583    ///         Ok(Self { })
584    ///     }
585    /// }
586    /// 
587    /// ```
588    #[inline(always)]
589    pub async fn is_component_exist<TComponent: 'static>(&self) -> bool {
590        self.core_context.is_component_exist(TypeId::of::<TComponent>()).await
591    }
592
593    /// Check component existence by type id
594    ///# Example
595    ///---
596    /// From root context
597    /// ```ignore
598    /// struct SomeComponent {}
599    /// 
600    /// let root_context = DependencyContext::new_root();
601    /// let is_exist: bool = root_context.is_component_with_type_id_exist(TypeId::of::<SomeComponent>()).await;
602    /// ```
603    /// 
604    /// ---
605    /// 
606    /// From ctor context
607    /// ```ignore
608    /// struct SomeComponent {}
609    /// 
610    /// #[async_trait_with_sync::async_trait(Sync)]
611    /// impl Constructor for SomeOtherComponent {
612    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
613    ///         let is_exist: bool = ctx.is_component_with_type_id_exist(TypeId::of::<SomeComponent>()).await;
614    ///         Ok(Self { })
615    ///     }
616    /// }
617    /// 
618    /// ```
619    #[inline(always)]
620    pub async fn is_component_with_type_id_exist(&self, component_type_id: TypeId) -> bool {
621        self.core_context.is_component_exist(component_type_id).await
622    }
623}
624
625#[cfg(feature = "blocking")]
626impl DependencyContext {
627    /// Register component witch implement trait Constructor (blocking version)
628    /// 
629    /// Remember, lifetime required smart pointers wrapper:
630    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
631    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
632    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
633    /// 
634    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
635    ///# Example
636    ///---
637    /// From root context
638    /// ```ignore
639    /// struct SomeComponent {}
640    /// 
641    /// let root_context = DependencyContext::new_root();
642    /// root_context.blocking_register_type::<SomeComponent>(LifeCycle::Transient).unwrap();
643    /// ```
644    /// 
645    /// ---
646    /// 
647    /// From ctor context
648    /// ```ignore
649    /// struct SomeComponent {}
650    /// 
651    /// #[async_trait_with_sync::async_trait(Sync)]
652    /// impl Constructor for SomeOtherComponent {
653    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
654    ///         // unwrap or map error to BuildDependencyError
655    ///         ctx.blocking_register_type::<SomeComponent>(LifeCycle::Transient).unwrap();
656    ///         Ok(Self { })
657    ///     }
658    /// }
659    /// 
660    /// ```
661    #[inline(always)]
662    pub fn blocking_register_type<TComponent: Constructor + Sync + Send + 'static>(&self, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
663        let self_copy = self.clone();
664        std::thread::spawn(move || {
665            self_copy.core_context.blocking_register::<TComponent>(Box::new(ComponentFromConstructor::<TComponent>::new()), life_cycle)
666        }).join().unwrap()
667    }
668
669    /// Register component from async closure (blocking version)
670    /// 
671    /// Remember, lifetime required smart pointers wrapper:
672    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
673    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
674    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
675    /// 
676    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
677    ///# Example
678    ///---
679    /// From root context
680    /// ```ignore
681    /// struct SomeComponent {}
682    /// 
683    /// let root_context = DependencyContext::new_root();
684    /// root_context.blocking_register_async_closure(async |_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).unwrap();
685    /// ```
686    /// 
687    /// ---
688    /// 
689    /// From ctor context
690    /// ```ignore
691    /// struct SomeComponent {}
692    /// 
693    /// #[async_trait_with_sync::async_trait(Sync)]
694    /// impl Constructor for SomeOtherComponent {
695    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
696    ///         // unwrap or map error to BuildDependencyError
697    ///         ctx.blocking_register_async_closure(async |_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).unwrap();
698    ///         Ok(Self { })
699    ///     }
700    /// }
701    /// 
702    /// ```
703    #[inline(always)]
704    pub fn blocking_register_async_closure<TComponent, TFuture, TClosure>(&self, closure: TClosure, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>>
705    where
706        TComponent: Sync + Send + 'static,
707        TFuture: Future<Output = BuildDependencyResult<TComponent>>,
708        TFuture: Sync + Send + 'static,
709        TClosure: Fn(DependencyContext) -> TFuture,
710        TClosure: Sync + Send + 'static,
711    {
712        let self_copy = self.clone();
713        std::thread::spawn(move || {
714            self_copy.core_context.blocking_register::<TComponent>(Box::new(ComponentFromAsyncClosure::<TComponent, TFuture, TClosure>::new(closure)), life_cycle)
715        }).join().unwrap()
716    }
717
718    /// Register component from closure (blocking version)
719    /// 
720    /// Remember, lifetime required smart pointers wrapper:
721    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
722    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
723    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
724    /// 
725    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
726    ///# Example
727    ///---
728    /// From root context
729    /// ```ignore
730    /// struct SomeComponent {}
731    /// 
732    /// let root_context = DependencyContext::new_root();
733    /// root_context.blocking_register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).unwrap();
734    /// ```
735    /// 
736    /// ---
737    /// 
738    /// From ctor context
739    /// ```ignore
740    /// struct SomeComponent {}
741    /// 
742    /// #[async_trait_with_sync::async_trait(Sync)]
743    /// impl Constructor for SomeOtherComponent {
744    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
745    ///         // unwrap or map error to BuildDependencyError
746    ///         ctx.blocking_register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).unwrap();
747    ///         Ok(Self { })
748    ///     }
749    /// }
750    /// 
751    /// ```
752    #[inline(always)]
753    pub fn blocking_register_closure<TComponent: Sync + Send + 'static, TClosure: Fn(DependencyContext) -> BuildDependencyResult<TComponent> + Sync + Send + 'static>(&self, closure: TClosure, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
754        let self_copy = self.clone();
755        std::thread::spawn(move || {
756            self_copy.core_context.blocking_register::<TComponent>(Box::new(ComponentFromClosure::<TComponent>::new(Box::new(closure))), life_cycle)
757        }).join().unwrap()
758    }
759
760    /// Register component instance as singleton (blocking version)
761    /// 
762    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
763    ///# Example
764    ///---
765    /// From root context
766    /// ```ignore
767    /// struct SomeComponent {}
768    /// 
769    /// let root_context = DependencyContext::new_root();
770    /// root_context.blocking_register_instance::<SomeComponent>(SomeComponent::new()).unwrap();
771    /// ```
772    /// 
773    /// ---
774    /// 
775    /// From ctor context
776    /// ```ignore
777    /// struct SomeComponent {}
778    /// 
779    /// #[async_trait_with_sync::async_trait(Sync)]
780    /// impl Constructor for SomeOtherComponent {
781    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
782    ///         // unwrap or map error to BuildDependencyError
783    ///         ctx.blocking_register_instance::<SomeComponent>(SomeComponent::new()).unwrap();
784    ///         Ok(Self { })
785    ///     }
786    /// }
787    /// 
788    /// ```
789    #[inline(always)]
790    pub fn blocking_register_instance<TComponent: Sync + Send + 'static>(&self, instance: TComponent) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
791        let self_copy = self.clone();
792        std::thread::spawn(move || {
793            self_copy.core_context.blocking_register::<TComponent>(Box::new(ComponentFromInstance::new(instance)), LifeCycle::Singleton)
794        }).join().unwrap()
795    }
796
797    /// Map component as service (blocking version)
798    ///# Example
799    ///---
800    /// From root context
801    /// ```ignore
802    /// struct SomeComponent {}
803    /// trait SomeService {}
804    /// 
805    /// let root_context = DependencyContext::new_root();
806    /// //...
807    /// 
808    /// // SomeComponent must be registered, or will be error
809    /// root_context.blocking_map_component::<SomeComponent, dyn SomeService>().unwrap();
810    /// ```
811    /// 
812    /// ---
813    /// 
814    /// From ctor context
815    /// ```ignore
816    /// struct SomeComponent {}
817    /// trait SomeService {}
818    /// 
819    /// #[async_trait_with_sync::async_trait(Sync)]
820    /// impl Constructor for SomeOtherComponent {
821    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
822    ///         // SomeComponent must be registered, or will be error
823    ///         // unwrap or map error to BuildDependencyError
824    ///         ctx.blocking_map_component::<SomeComponent, dyn SomeService>().unwrap();
825    ///         Ok(Self { })
826    ///     }
827    /// }
828    /// 
829    /// ```
830    #[inline(always)]
831    pub fn blocking_map_component<TComponent: Sync + Send + 'static, TService: ?Sized + Sync + Send + 'static>(&self) -> MapComponentResult<Arc<CoreContext>> where TComponent: Unsize<TService> {
832        let self_copy = self.clone();
833        std::thread::spawn(move || {
834            self_copy.core_context.blocking_map_component::<TComponent, TService>()
835        }).join().unwrap()
836    }
837
838    /// Resolve first component, mapped to service (blocking version)
839    /// ``` ignore
840    /// // You can resolve transient like:
841    /// ctx.blocking_resolve::<Box<dyn Service>>().unwrap()
842    /// ctx.blocking_resolve::<Box<Component>>().unwrap()
843    /// 
844    /// // You can resolve singleton like:
845    /// ctx.blocking_resolve::<Arc<dyn Service>>().unwrap()
846    /// ctx.blocking_resolve::<Arc<Component>>().unwrap()
847    /// 
848    /// // You can resolve context dependent like:
849    /// ctx.blocking_resolve::<Weak<dyn Service>>().unwrap()
850    /// ctx.blocking_resolve::<Weak<Component>>().unwrap()
851    /// 
852    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
853    /// ctx.blocking_resolve::<Weak<RwLock<dyn Service>>>().unwrap()
854    ///  
855    /// ```
856    ///# Example
857    ///---
858    /// From root context
859    /// ```ignore
860    /// trait SomeService {}
861    /// 
862    /// let root_context = DependencyContext::new_root();
863    /// let service: Box<dyn SomeTrait> = root_context.blocking_resolve::<Box<dyn SomeService>>().unwrap();
864    /// ```
865    /// 
866    /// ---
867    /// 
868    /// From ctor context
869    /// ```ignore
870    /// trait SomeService {}
871    /// 
872    /// #[async_trait_with_sync::async_trait(Sync)]
873    /// impl Constructor for SomeOtherComponent {
874    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
875    ///         // unwrap or map error to BuildDependencyError
876    ///         let service: Box<dyn SomeTrait> = ctx.blocking_resolve::<Box<dyn SomeService>>().unwrap();
877    ///         Ok(Self { })
878    ///     }
879    /// }
880    /// 
881    /// ```
882    #[inline(always)]
883    pub fn blocking_resolve<TService: Sync + Send + 'static>(&self) -> BuildDependencyResult<TService> {
884        let self_copy = self.clone();
885        std::thread::spawn(move || {
886            self_copy.core_context.blocking_resolve::<TService>(self_copy.id.clone(), self_copy.local_context.clone())
887        }).join().unwrap()
888    }
889
890    /// Resolve component with TypeId, mapped to service (blocking version)
891    /// That may be helpful in case, when you need current component, type is lost, but you can save TypeId as variable
892    /// ``` ignore
893    /// // You can resolve transient like:
894    /// ctx.blocking_resolve_by_type_id::<Box<dyn Service>>(TypeId::of::<Component>()).unwrap()
895    /// ctx.blocking_resolve_by_type_id::<Box<Component>>(TypeId::of::<Component>()).unwrap()
896    /// 
897    /// // You can resolve singleton like:
898    /// ctx.blocking_resolve_by_type_id::<Arc<dyn Service>>(TypeId::of::<Component>()).unwrap()
899    /// ctx.blocking_resolve_by_type_id::<Arc<Component>>(TypeId::of::<Component>()).unwrap()
900    /// 
901    /// // You can resolve context dependent like:
902    /// ctx.blocking_resolve_by_type_id::<Weak<dyn Service>>(TypeId::of::<Component>()).unwrap()
903    /// ctx.blocking_resolve_by_type_id::<Weak<Component>>(TypeId::of::<Component>()).unwrap()
904    /// 
905    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
906    /// ctx.blocking_resolve_by_type_id::<Weak<RwLock<dyn Service>>>(TypeId::of::<Component>()).unwrap()
907    ///  
908    /// ```
909    ///# Example
910    ///---
911    /// From root context
912    /// ```ignore
913    /// struct SomeComponent {}
914    /// trait SomeService {}
915    /// 
916    /// let root_context = DependencyContext::new_root();
917    /// let service: Box<dyn SomeTrait> = root_context.blocking_resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).unwrap();
918    /// ```
919    /// 
920    /// ---
921    /// 
922    /// From ctor context
923    /// ```ignore
924    /// struct SomeComponent {}
925    /// trait SomeService {}
926    /// 
927    /// #[async_trait_with_sync::async_trait(Sync)]
928    /// impl Constructor for SomeOtherComponent {
929    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
930    ///         // unwrap or map error to BuildDependencyError
931    ///         let service: Box<dyn SomeTrait> = ctx.blocking_resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).unwrap();
932    ///         Ok(Self { })
933    ///     }
934    /// }
935    /// 
936    /// ```
937    #[inline(always)]
938    pub fn blocking_resolve_by_type_id<TService: Sync + Send + 'static>(&self, component_type_id: TypeId) -> BuildDependencyResult<TService> {
939        let self_copy = self.clone();
940        std::thread::spawn(move || {
941            self_copy.core_context.blocking_resolve_by_type_id::<TService>(component_type_id, self_copy.id.clone(), self_copy.local_context.clone())
942        }).join().unwrap()
943    }
944
945    /// Resolve all component, mapped to service (blocking version)
946    /// ``` ignore
947    /// // You can resolve transient like:
948    /// ctx.blocking_resolve_collection::<Box<dyn Service>>().unwrap()
949    /// ctx.blocking_resolve_collection::<Box<Component>>().unwrap()
950    /// 
951    /// // You can resolve singleton like:
952    /// ctx.blocking_resolve_collection::<Arc<dyn Service>>().unwrap()
953    /// ctx.blocking_resolve_collection::<Arc<Component>>().unwrap()
954    /// 
955    /// // You can resolve context dependent like:
956    /// ctx.blocking_resolve_collection::<Weak<dyn Service>>().unwrap()
957    /// ctx.blocking_resolve_collection::<Weak<Component>>().unwrap()
958    /// 
959    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
960    /// ctx.blocking_resolve_collection::<Weak<RwLock<dyn Service>>>().unwrap()
961    ///  
962    /// ```
963    ///# Example
964    ///---
965    /// From root context
966    /// ```ignore
967    /// trait SomeService {}
968    /// 
969    /// let root_context = DependencyContext::new_root();
970    /// let collection: Vec<Box<dyn SomeService>> = root_context.blocking_resolve_collection::<Box<dyn SomeService>>().unwrap();
971    /// ```
972    /// 
973    /// ---
974    /// 
975    /// From ctor context
976    /// ```ignore
977    /// trait SomeService {}
978    /// 
979    /// #[async_trait_with_sync::async_trait(Sync)]
980    /// impl Constructor for SomeOtherComponent {
981    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
982    ///         // unwrap or map error to BuildDependencyError
983    ///         let collection: Vec<Box<dyn SomeService>> = ctx.blocking_resolve_collection::<Box<dyn SomeService>>().unwrap();
984    ///         Ok(Self { })
985    ///     }
986    /// }
987    /// 
988    /// ```
989    #[inline(always)]
990    pub fn blocking_resolve_collection<TService: Sync + Send + 'static>(&self) -> BuildDependencyResult<Vec<TService>> {
991        let self_copy = self.clone();
992        std::thread::spawn(move || {
993            self_copy.core_context.blocking_resolve_collection::<TService>(self_copy.id.clone(), self_copy.local_context.clone())
994        }).join().unwrap()
995    }
996
997    /// Delete component (blocking version)
998    ///# Example
999    ///---
1000    /// From root context
1001    /// ```ignore
1002    /// struct SomeComponent {}
1003    /// 
1004    /// let root_context = DependencyContext::new_root();
1005    /// root_context.blocking_delete_component::<SomeComponent>().unwrap();
1006    /// ```
1007    /// 
1008    /// ---
1009    /// 
1010    /// From ctor context
1011    /// ```ignore
1012    /// struct SomeComponent {}
1013    /// 
1014    /// #[async_trait_with_sync::async_trait(Sync)]
1015    /// impl Constructor for SomeOtherComponent {
1016    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1017    ///         // unwrap or map error to BuildDependencyError
1018    ///         ctx.blocking_delete_component::<SomeComponent>().unwrap();
1019    ///         Ok(Self { })
1020    ///     }
1021    /// }
1022    /// 
1023    /// ```
1024    #[inline(always)]
1025    pub fn blocking_delete_component<TComponent: 'static>(&self) -> DeleteComponentResult<()> {
1026        let self_copy = self.clone();
1027        std::thread::spawn(move || {
1028            self_copy.core_context.blocking_delete_component::<TComponent>()
1029        }).join().unwrap()
1030    }
1031
1032    /// Check service existence (blocking version)
1033    /// ``` ignore
1034    /// // You can check transient like:
1035    /// ctx.blocking_is_service_exist::<Box<dyn Service>>().unwrap()
1036    /// ctx.blocking_is_service_exist::<Box<Component>>().unwrap()
1037    /// 
1038    /// // You can check singleton like:
1039    /// ctx.blocking_is_service_exist::<Arc<dyn Service>>().unwrap()
1040    /// ctx.blocking_is_service_exist::<Arc<Component>>().unwrap()
1041    /// 
1042    /// // You can check context dependent like:
1043    /// ctx.blocking_is_service_exist::<Weak<dyn Service>>().unwrap()
1044    /// ctx.blocking_is_service_exist::<Weak<Component>>().unwrap()
1045    /// 
1046    /// // remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
1047    /// ctx.blocking_is_service_exist::<Weak<RwLock<dyn Service>>>().unwrap()
1048    ///  
1049    /// ```
1050    ///# Example
1051    ///---
1052    /// From root context
1053    /// ```ignore
1054    /// trait SomeService {}
1055    /// 
1056    /// let root_context = DependencyContext::new_root();
1057    /// let is_exist: bool = root_context.blocking_is_service_exist::<Box<dyn SomeService>>();
1058    /// ```
1059    /// 
1060    /// ---
1061    /// 
1062    /// From ctor context
1063    /// ```ignore
1064    /// trait SomeService {}
1065    /// 
1066    /// #[async_trait_with_sync::async_trait(Sync)]
1067    /// impl Constructor for SomeOtherComponent {
1068    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1069    ///         let is_exist: bool = ctx.blocking_is_service_exist::<Box<dyn SomeService>>();
1070    ///         Ok(Self { })
1071    ///     }
1072    /// }
1073    /// 
1074    /// ```
1075    #[inline(always)]
1076    pub fn blocking_is_service_exist<TService: 'static>(&self) -> bool {
1077        let self_copy = self.clone();
1078        std::thread::spawn(move || {
1079            self_copy.core_context.blocking_is_service_exist(TypeId::of::<TService>())
1080        }).join().unwrap()
1081    }
1082
1083    /// Check service existence by type id (blocking version)
1084    /// ``` ignore
1085    /// // You can check transient like:
1086    /// ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Box<dyn Service>>()).unwrap()
1087    /// ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Box<Component>>()).unwrap()
1088    /// 
1089    /// // You can check singleton like:
1090    /// ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Arc<dyn Service>>()).unwrap()
1091    /// ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Arc<Component>>()).unwrap()
1092    /// 
1093    /// // You can check context dependent like:
1094    /// ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Weak<dyn Service>>()).unwrap()
1095    /// ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Weak<Component>>()).unwrap()
1096    /// 
1097    /// // remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
1098    /// ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Weak<RwLock<dyn Service>>>()).unwrap()
1099    ///  
1100    /// ```
1101    ///# Example
1102    ///---
1103    /// From root context
1104    /// ```ignore
1105    /// trait SomeService {}
1106    /// 
1107    /// let root_context = DependencyContext::new_root();
1108    /// let is_exist: bool = root_context.blocking_is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>());
1109    /// ```
1110    /// 
1111    /// ---
1112    /// 
1113    /// From ctor context
1114    /// ```ignore
1115    /// trait SomeService {}
1116    /// 
1117    /// #[async_trait_with_sync::async_trait(Sync)]
1118    /// impl Constructor for SomeOtherComponent {
1119    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1120    ///         let is_exist: bool = ctx.blocking_is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>());
1121    ///         Ok(Self { })
1122    ///     }
1123    /// }
1124    /// 
1125    /// ```
1126    #[inline(always)]
1127    pub fn blocking_is_service_with_type_id_exist(&self, service_type_id: TypeId) -> bool {
1128        let self_copy = self.clone();
1129        std::thread::spawn(move || {
1130            self_copy.core_context.blocking_is_service_exist(service_type_id)
1131        }).join().unwrap()
1132    }
1133
1134    /// Check component existence (blocking version)
1135    ///# Example
1136    ///---
1137    /// From root context
1138    /// ```ignore
1139    /// struct SomeComponent {}
1140    /// 
1141    /// let root_context = DependencyContext::new_root();
1142    /// let is_exist: bool = root_context.blocking_is_component_exist::<SomeComponent>();
1143    /// ```
1144    /// 
1145    /// ---
1146    /// 
1147    /// From ctor context
1148    /// ```ignore
1149    /// struct SomeComponent {}
1150    /// 
1151    /// #[async_trait_with_sync::async_trait(Sync)]
1152    /// impl Constructor for SomeOtherComponent {
1153    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1154    ///         let is_exist: bool = ctx.blocking_is_component_exist::<SomeComponent>();
1155    ///         Ok(Self { })
1156    ///     }
1157    /// }
1158    /// 
1159    /// ```
1160    #[inline(always)]
1161    pub fn blocking_is_component_exist<TComponent: 'static>(&self) -> bool {
1162        let self_copy = self.clone();
1163        std::thread::spawn(move || {
1164            self_copy.core_context.blocking_is_component_exist(TypeId::of::<TComponent>())
1165        }).join().unwrap()
1166    }
1167
1168    /// Check component existence by type id (blocking version)
1169    ///# Example
1170    ///---
1171    /// From root context
1172    /// ```ignore
1173    /// struct SomeComponent {}
1174    /// 
1175    /// let root_context = DependencyContext::new_root();
1176    /// let is_exist: bool = root_context.blocking_is_component_with_type_id_exist(TypeId::of::<SomeComponent>());
1177    /// ```
1178    /// 
1179    /// ---
1180    /// 
1181    /// From ctor context
1182    /// ```ignore
1183    /// struct SomeComponent {}
1184    /// 
1185    /// #[async_trait_with_sync::async_trait(Sync)]
1186    /// impl Constructor for SomeOtherComponent {
1187    ///     async fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1188    ///         let is_exist: bool = ctx.blocking_is_component_with_type_id_exist(TypeId::of::<SomeComponent>());
1189    ///         Ok(Self { })
1190    ///     }
1191    /// }
1192    /// 
1193    /// ```
1194    #[inline(always)]
1195    pub fn blocking_is_component_with_type_id_exist(&self, component_type_id: TypeId) -> bool {
1196        let self_copy = self.clone();
1197        std::thread::spawn(move || {
1198            self_copy.core_context.blocking_is_component_exist(component_type_id)
1199        }).join().unwrap()
1200    }
1201}
1202
1203#[cfg(not(feature = "async-mode"))]
1204impl DependencyContext {
1205    /// Register component witch implement trait Constructor
1206    /// 
1207    /// Remember, lifetime required smart pointers wrapper:
1208    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
1209    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
1210    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
1211    /// 
1212    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
1213    ///# Example
1214    ///---
1215    /// From root context
1216    /// ```ignore
1217    /// struct SomeComponent {}
1218    /// 
1219    /// let root_context = DependencyContext::new_root();
1220    /// root_context.register_type::<SomeComponent>(LifeCycle::Transient).unwrap();
1221    /// ```
1222    /// 
1223    /// ---
1224    /// 
1225    /// From ctor context
1226    /// ```ignore
1227    /// struct SomeComponent {}
1228    /// 
1229    /// impl Constructor for SomeOtherComponent {
1230    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1231    ///         // unwrap or map error to BuildDependencyError
1232    ///         ctx.register_type::<SomeComponent>(LifeCycle::Transient).unwrap();
1233    ///         Ok(Self { })
1234    ///     }
1235    /// }
1236    /// 
1237    /// ```
1238    #[inline(always)]
1239    pub fn register_type<TComponent: Constructor + Sync + Send + 'static>(&self, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
1240        self.core_context.register::<TComponent>(Box::new(ComponentFromConstructor::<TComponent>::new()), life_cycle)
1241    }
1242
1243    /// Register component from closure
1244    /// 
1245    /// Remember, lifetime required smart pointers wrapper:
1246    /// * if register Component as Transient, resolve as Component or Box<dyn Service>
1247    /// * if register Component as Singleton, resolve as Arc<Component> or Arc<dyn Service>
1248    /// * if register Component as ContextDependent, resolve as Weak<Component> or Weak<dyn Service>
1249    /// 
1250    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
1251    ///# Example
1252    ///---
1253    /// From root context
1254    /// ```ignore
1255    /// struct SomeComponent {}
1256    /// 
1257    /// let root_context = DependencyContext::new_root();
1258    /// root_context.register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).unwrap();
1259    /// ```
1260    /// 
1261    /// ---
1262    /// 
1263    /// From ctor context
1264    /// ```ignore
1265    /// struct SomeComponent {}
1266    /// 
1267    /// impl Constructor for SomeOtherComponent {
1268    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1269    ///         // unwrap or map error to BuildDependencyError
1270    ///         ctx.register_closure(|_ctx| Ok(SomeComponent::new()), LifeCycle::Transient).unwrap();
1271    ///         Ok(Self { })
1272    ///     }
1273    /// }
1274    /// 
1275    /// ```
1276    #[inline(always)]
1277    pub fn register_closure<TComponent: Sync + Send + 'static, TClosure: Fn(DependencyContext) -> BuildDependencyResult<TComponent> + Sync + Send + 'static>(&self, closure: TClosure, life_cycle: LifeCycle) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
1278        self.core_context.register::<TComponent>(Box::new(ComponentFromClosure::<TComponent>::new(Box::new(closure))), life_cycle)
1279    }
1280
1281    /// Register component instance as singleton
1282    /// 
1283    /// Remember, for mutable Singleton/ContextDependent instance, you need register component, wrapped in RwLock<T> 
1284    ///# Example
1285    ///---
1286    /// From root context
1287    /// ```ignore
1288    /// struct SomeComponent {}
1289    /// 
1290    /// let root_context = DependencyContext::new_root();
1291    /// root_context.register_instance::<SomeComponent>(SomeComponent::new()).unwrap();
1292    /// ```
1293    /// 
1294    /// ---
1295    /// 
1296    /// From ctor context
1297    /// ```ignore
1298    /// struct SomeComponent {}
1299    /// 
1300    /// impl Constructor for SomeOtherComponent {
1301    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1302    ///         // unwrap or map error to BuildDependencyError
1303    ///         ctx.register_instance::<SomeComponent>(SomeComponent::new()).unwrap();
1304    ///         Ok(Self { })
1305    ///     }
1306    /// }
1307    /// 
1308    /// ```
1309    #[inline(always)]
1310    pub fn register_instance<TComponent: Sync + Send + 'static>(&self, instance: TComponent) -> AddDependencyResult<ServiceMappingBuilder<TComponent>> {
1311        self.core_context.register::<TComponent>(Box::new(ComponentFromInstance::new(instance)), LifeCycle::Singleton)
1312    }
1313
1314    /// Map component as service
1315    ///# Example
1316    ///---
1317    /// From root context
1318    /// ```ignore
1319    /// struct SomeComponent {}
1320    /// trait SomeService {}
1321    /// 
1322    /// let root_context = DependencyContext::new_root();
1323    /// //...
1324    /// 
1325    /// // SomeComponent must be registered, or will be error
1326    /// root_context.map_component::<SomeComponent, dyn SomeService>().unwrap();
1327    /// ```
1328    /// 
1329    /// ---
1330    /// 
1331    /// From ctor context
1332    /// ```ignore
1333    /// struct SomeComponent {}
1334    /// trait SomeService {}
1335    /// 
1336    /// impl Constructor for SomeOtherComponent {
1337    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1338    ///         // SomeComponent must be registered, or will be error
1339    ///         // unwrap or map error to BuildDependencyError
1340    ///         ctx.map_component::<SomeComponent, dyn SomeService>().unwrap();
1341    ///         Ok(Self { })
1342    ///     }
1343    /// }
1344    /// 
1345    /// ```
1346    #[inline(always)]
1347    pub fn map_component<TComponent: Sync + Send + 'static, TService: ?Sized + Sync + Send + 'static>(&self) -> MapComponentResult<Arc<CoreContext>> where TComponent: Unsize<TService> {
1348        self.core_context.map_component::<TComponent, TService>()
1349    }
1350
1351    /// Resolve first component, mapped to service
1352    /// ``` ignore
1353    /// // You can resolve transient like:
1354    /// ctx.resolve::<Box<dyn Service>>().unwrap()
1355    /// ctx.resolve::<Box<Component>>().unwrap()
1356    /// 
1357    /// // You can resolve singleton like:
1358    /// ctx.resolve::<Arc<dyn Service>>().unwrap()
1359    /// ctx.resolve::<Arc<Component>>().unwrap()
1360    /// 
1361    /// // You can resolve context dependent like:
1362    /// ctx.resolve::<Weak<dyn Service>>().unwrap()
1363    /// ctx.resolve::<Weak<Component>>().unwrap()
1364    /// 
1365    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
1366    /// ctx.resolve::<Weak<RwLock<dyn Service>>>().unwrap()
1367    ///  
1368    /// ```
1369    ///# Example
1370    ///---
1371    /// From root context
1372    /// ```ignore
1373    /// trait SomeService {}
1374    /// 
1375    /// let root_context = DependencyContext::new_root();
1376    /// let service: Box<dyn SomeTrait> = root_context.resolve::<Box<dyn SomeService>>().unwrap();
1377    /// ```
1378    /// 
1379    /// ---
1380    /// 
1381    /// From ctor context
1382    /// ```ignore
1383    /// trait SomeService {}
1384    /// 
1385    /// impl Constructor for SomeOtherComponent {
1386    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1387    ///         // unwrap or map error to BuildDependencyError
1388    ///         let service: Box<dyn SomeTrait> = ctx.resolve::<Box<dyn SomeService>>().unwrap();
1389    ///         Ok(Self { })
1390    ///     }
1391    /// }
1392    /// 
1393    /// ```
1394    #[inline(always)]
1395    pub fn resolve<'a, TService: Sync + Send + 'static>(&'a self) -> BuildDependencyResult<TService> {
1396        self.core_context.resolve::<TService>(self.id.clone(), self.local_context.clone())
1397    }
1398
1399    /// Resolve component with TypeId, mapped to service
1400    /// That may be helpful in case, when you need current component, type is lost, but you can save TypeId as variable
1401    /// ``` ignore
1402    /// // You can resolve transient like:
1403    /// ctx.resolve_by_type_id::<Box<dyn Service>>(TypeId::of::<Component>()).unwrap()
1404    /// ctx.resolve_by_type_id::<Box<Component>>(TypeId::of::<Component>()).unwrap()
1405    /// 
1406    /// // You can resolve singleton like:
1407    /// ctx.resolve_by_type_id::<Arc<dyn Service>>(TypeId::of::<Component>()).unwrap()
1408    /// ctx.resolve_by_type_id::<Arc<Component>>(TypeId::of::<Component>()).unwrap()
1409    /// 
1410    /// // You can resolve context dependent like:
1411    /// ctx.resolve_by_type_id::<Weak<dyn Service>>(TypeId::of::<Component>()).unwrap()
1412    /// ctx.resolve_by_type_id::<Weak<Component>>(TypeId::of::<Component>()).unwrap()
1413    /// 
1414    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
1415    /// ctx.resolve_by_type_id::<Weak<RwLock<dyn Service>>>(TypeId::of::<Component>()).unwrap()
1416    ///  
1417    /// ```
1418    ///# Example
1419    ///---
1420    /// From root context
1421    /// ```ignore
1422    /// struct SomeComponent {}
1423    /// trait SomeService {}
1424    /// 
1425    /// let root_context = DependencyContext::new_root();
1426    /// let service: Box<dyn SomeTrait> = root_context.resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).unwrap();
1427    /// ```
1428    /// 
1429    /// ---
1430    /// 
1431    /// From ctor context
1432    /// ```ignore
1433    /// struct SomeComponent {}
1434    /// trait SomeService {}
1435    /// 
1436    /// impl Constructor for SomeOtherComponent {
1437    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1438    ///         // unwrap or map error to BuildDependencyError
1439    ///         let service: Box<dyn SomeTrait> = ctx.resolve_by_type_id::<Box<dyn SomeService>>(TypeId::of::<SomeComponent>()).unwrap();
1440    ///         Ok(Self { })
1441    ///     }
1442    /// }
1443    /// 
1444    /// ```
1445    #[inline(always)]
1446    pub fn resolve_by_type_id<TService: Sync + Send + 'static>(&self, component_type_id: TypeId) -> BuildDependencyResult<TService> {
1447        self.core_context.resolve_by_type_id::<TService>(component_type_id, self.id.clone(), self.local_context.clone())
1448    }
1449
1450    /// Resolve all component, mapped to service
1451    /// ``` ignore
1452    /// // You can resolve transient like:
1453    /// ctx.resolve_collection::<Box<dyn Service>>().unwrap()
1454    /// ctx.resolve_collection::<Box<Component>>().unwrap()
1455    /// 
1456    /// // You can resolve singleton like:
1457    /// ctx.resolve_collection::<Arc<dyn Service>>().unwrap()
1458    /// ctx.resolve_collection::<Arc<Component>>().unwrap()
1459    /// 
1460    /// // You can resolve context dependent like:
1461    /// ctx.resolve_collection::<Weak<dyn Service>>().unwrap()
1462    /// ctx.resolve_collection::<Weak<Component>>().unwrap()
1463    /// 
1464    /// // for mutable Arc and Weak, register as RwLock<Component>, map as RwLock<dyn Service>, and resolve like:
1465    /// ctx.resolve_collection::<Weak<RwLock<dyn Service>>>().unwrap()
1466    ///  
1467    /// ```
1468    ///# Example
1469    ///---
1470    /// From root context
1471    /// ```ignore
1472    /// trait SomeService {}
1473    /// 
1474    /// let root_context = DependencyContext::new_root();
1475    /// let collection: Vec<Box<dyn SomeService>> = root_context.resolve_collection::<Box<dyn SomeService>>().unwrap();
1476    /// ```
1477    /// 
1478    /// ---
1479    /// 
1480    /// From ctor context
1481    /// ```ignore
1482    /// trait SomeService {}
1483    /// 
1484    /// impl Constructor for SomeOtherComponent {
1485    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1486    ///         // unwrap or map error to BuildDependencyError
1487    ///         let collection: Vec<Box<dyn SomeService>> = ctx.resolve_collection::<Box<dyn SomeService>>().unwrap();
1488    ///         Ok(Self { })
1489    ///     }
1490    /// }
1491    /// 
1492    /// ```
1493    #[inline(always)]
1494    pub fn resolve_collection<TService: Sync + Send + 'static>(&self) -> BuildDependencyResult<Vec<TService>> {
1495        self.core_context.resolve_collection::<TService>(self.id.clone(), self.local_context.clone())
1496    }
1497
1498    /// Delete component
1499    ///# Example
1500    ///---
1501    /// From root context
1502    /// ```ignore
1503    /// struct SomeComponent {}
1504    /// 
1505    /// let root_context = DependencyContext::new_root();
1506    /// root_context.delete_component::<SomeComponent>().unwrap();
1507    /// ```
1508    /// 
1509    /// ---
1510    /// 
1511    /// From ctor context
1512    /// ```ignore
1513    /// struct SomeComponent {}
1514    /// 
1515    /// impl Constructor for SomeOtherComponent {
1516    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1517    ///         // unwrap or map error to BuildDependencyError
1518    ///         ctx.delete_component::<SomeComponent>().unwrap();
1519    ///         Ok(Self { })
1520    ///     }
1521    /// }
1522    /// 
1523    /// ```
1524    #[inline(always)]
1525    pub fn delete_component<TComponent: 'static>(&self) -> DeleteComponentResult<()> {
1526        self.core_context.delete_component::<TComponent>()
1527    }
1528
1529    /// Check service existence
1530    /// ``` ignore
1531    /// // You can check transient like:
1532    /// ctx.is_service_exist::<Box<dyn Service>>().unwrap()
1533    /// ctx.is_service_exist::<Box<Component>>().unwrap()
1534    /// 
1535    /// // You can check singleton like:
1536    /// ctx.is_service_exist::<Arc<dyn Service>>().unwrap()
1537    /// ctx.is_service_exist::<Arc<Component>>().unwrap()
1538    /// 
1539    /// // You can check context dependent like:
1540    /// ctx.is_service_exist::<Weak<dyn Service>>().unwrap()
1541    /// ctx.is_service_exist::<Weak<Component>>().unwrap()
1542    /// 
1543    /// // remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
1544    /// ctx.is_service_exist::<Weak<RwLock<dyn Service>>>().unwrap()
1545    ///  
1546    /// ```
1547    ///# Example
1548    ///---
1549    /// From root context
1550    /// ```ignore
1551    /// trait SomeService {}
1552    /// 
1553    /// let root_context = DependencyContext::new_root();
1554    /// let is_exist: bool = root_context.is_service_exist::<Box<dyn SomeService>>();
1555    /// ```
1556    /// 
1557    /// ---
1558    /// 
1559    /// From ctor context
1560    /// ```ignore
1561    /// trait SomeService {}
1562    /// 
1563    /// impl Constructor for SomeOtherComponent {
1564    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1565    ///         let is_exist: bool = ctx.is_service_exist::<Box<dyn SomeService>>();
1566    ///         Ok(Self { })
1567    ///     }
1568    /// }
1569    /// 
1570    /// ```
1571    #[inline(always)]
1572    pub fn is_service_exist<TService: 'static>(&self) -> bool {
1573        self.core_context.is_service_exist(TypeId::of::<TService>())
1574    }
1575
1576    /// Check service existence by type id
1577    /// ``` ignore
1578    /// // You can check transient like:
1579    /// ctx.is_service_with_type_id_exist(TypeId::of::<Box<dyn Service>>()).unwrap()
1580    /// ctx.is_service_with_type_id_exist(TypeId::of::<Box<Component>>()).unwrap()
1581    /// 
1582    /// // You can check singleton like:
1583    /// ctx.is_service_with_type_id_exist(TypeId::of::<Arc<dyn Service>>()).unwrap()
1584    /// ctx.is_service_with_type_id_exist(TypeId::of::<Arc<Component>>()).unwrap()
1585    /// 
1586    /// // You can check context dependent like:
1587    /// ctx.is_service_with_type_id_exist(TypeId::of::<Weak<dyn Service>>()).unwrap()
1588    /// ctx.is_service_with_type_id_exist(TypeId::of::<Weak<Component>>()).unwrap()
1589    /// 
1590    /// // remember, if you register as RwLock<Component>, map as RwLock<dyn Service>, check like:
1591    /// ctx.is_service_with_type_id_exist(TypeId::of::<Weak<RwLock<dyn Service>>>()).unwrap()
1592    ///  
1593    /// ```
1594    ///# Example
1595    ///---
1596    /// From root context
1597    /// ```ignore
1598    /// trait SomeService {}
1599    /// 
1600    /// let root_context = DependencyContext::new_root();
1601    /// let is_exist: bool = root_context.is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>());
1602    /// ```
1603    /// 
1604    /// ---
1605    /// 
1606    /// From ctor context
1607    /// ```ignore
1608    /// trait SomeService {}
1609    /// 
1610    /// impl Constructor for SomeOtherComponent {
1611    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1612    ///         let is_exist: bool = ctx.is_service_with_type_id_exist(TypeId::of::<Box<dyn SomeService>>());
1613    ///         Ok(Self { })
1614    ///     }
1615    /// }
1616    /// 
1617    /// ```
1618    #[inline(always)]
1619    pub fn is_service_with_type_id_exist(&self, service_type_id: TypeId) -> bool {
1620        self.core_context.is_service_exist(service_type_id)
1621    }
1622
1623    /// Check component existence
1624    ///# Example
1625    ///---
1626    /// From root context
1627    /// ```ignore
1628    /// struct SomeComponent {}
1629    /// 
1630    /// let root_context = DependencyContext::new_root();
1631    /// let is_exist: bool = root_context.is_component_exist::<SomeComponent>();
1632    /// ```
1633    /// 
1634    /// ---
1635    /// 
1636    /// From ctor context
1637    /// ```ignore
1638    /// struct SomeComponent {}
1639    /// 
1640    /// impl Constructor for SomeOtherComponent {
1641    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1642    ///         let is_exist: bool = ctx.is_component_exist::<SomeComponent>();
1643    ///         Ok(Self { })
1644    ///     }
1645    /// }
1646    /// 
1647    /// ```
1648    #[inline(always)]
1649    pub fn is_component_exist<TComponent: 'static>(&self) -> bool {
1650        self.core_context.is_component_exist(TypeId::of::<TComponent>())
1651    }
1652
1653    /// Check component existence by type id
1654    ///# Example
1655    ///---
1656    /// From root context
1657    /// ```ignore
1658    /// struct SomeComponent {}
1659    /// 
1660    /// let root_context = DependencyContext::new_root();
1661    /// let is_exist: bool = root_context.is_component_with_type_id_exist(TypeId::of::<SomeComponent>());
1662    /// ```
1663    /// 
1664    /// ---
1665    /// 
1666    /// From ctor context
1667    /// ```ignore
1668    /// struct SomeComponent {}
1669    /// 
1670    /// impl Constructor for SomeOtherComponent {
1671    ///     fn ctor(ctx: crate::DependencyContext) -> BuildDependencyResult<Self> {
1672    ///         let is_exist: bool = ctx.is_component_with_type_id_exist(TypeId::of::<SomeComponent>());
1673    ///         Ok(Self { })
1674    ///     }
1675    /// }
1676    /// 
1677    /// ```
1678    #[inline(always)]
1679    pub fn is_component_with_type_id_exist(&self, component_type_id: TypeId) -> bool {
1680        self.core_context.is_component_exist(component_type_id)
1681    }
1682}