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}