reifydb_core/util/ioc/
mod.rs1pub mod resolve_arc;
5pub mod resolve_rc;
6
7use std::{
8 any::{Any, TypeId, type_name},
9 collections::HashMap,
10 sync::{Arc, RwLock},
11};
12
13use reifydb_type::Result;
14
15use crate::internal_error;
16
17struct BoxedValue {
18 value: Box<dyn Any + Send + Sync>,
19}
20
21impl BoxedValue {
22 fn new<T: Clone + Any + Send + Sync + 'static>(value: T) -> Self {
23 Self {
24 value: Box::new(value),
25 }
26 }
27
28 fn value<T: Clone + Any + Send + Sync + 'static>(&self) -> Option<T> {
29 self.value.downcast_ref::<T>().cloned()
30 }
31}
32
33pub struct IocContainer {
35 dependencies: Arc<RwLock<HashMap<TypeId, BoxedValue>>>,
36}
37
38impl IocContainer {
39 pub fn new() -> Self {
40 Self {
41 dependencies: Arc::new(RwLock::new(HashMap::new())),
42 }
43 }
44
45 pub fn register<T: Clone + Any + Send + Sync + 'static>(self, service: T) -> Self {
46 self.dependencies.write().unwrap().insert(TypeId::of::<T>(), BoxedValue::new(service));
47 self
48 }
49
50 pub fn register_service<T: Clone + Any + Send + Sync + 'static>(&self, service: T) {
52 self.dependencies.write().unwrap().insert(TypeId::of::<T>(), BoxedValue::new(service));
53 }
54
55 pub fn clear(&self) {
56 self.dependencies.write().unwrap().clear();
57 }
58
59 pub fn resolve<T: Clone + Any + Send + Sync + 'static>(&self) -> Result<T> {
60 self.dependencies
61 .read()
62 .unwrap()
63 .get(&TypeId::of::<T>())
64 .and_then(|boxed| boxed.value::<T>())
65 .ok_or_else(|| internal_error!("Type {} not registered in IoC container", type_name::<T>()))
66 }
67
68 pub fn try_resolve<T: Clone + Any + Send + Sync + 'static>(&self) -> Option<T> {
72 self.dependencies.read().unwrap().get(&TypeId::of::<T>()).and_then(|boxed| boxed.value::<T>())
73 }
74}
75
76impl Clone for IocContainer {
77 fn clone(&self) -> Self {
78 Self {
79 dependencies: self.dependencies.clone(),
80 }
81 }
82}
83
84impl Default for IocContainer {
85 fn default() -> Self {
86 Self::new()
87 }
88}