reactive_graph_di/
lib.rs

1use fxhash::FxHashMap;
2use log::error;
3use springtime_di::component::Injectable;
4use springtime_di::component_registry::ComponentAliasMetadata;
5use springtime_di::component_registry::ComponentDefinition;
6use springtime_di::component_registry::ComponentDefinitionRegistry;
7use springtime_di::component_registry::ComponentDefinitionRegistryError;
8use springtime_di::component_registry::ComponentMetadata;
9use springtime_di::component_registry::StaticComponentDefinitionRegistry;
10use springtime_di::component_registry::conditional::SimpleContextFactory;
11use springtime_di::factory::ComponentFactory;
12use springtime_di::factory::ScopeFactoryPtr;
13use springtime_di::instance_provider::CastFunction;
14use springtime_di::instance_provider::ComponentInstanceAnyPtr;
15use springtime_di::instance_provider::ComponentInstanceProvider;
16use springtime_di::instance_provider::ComponentInstanceProviderError;
17use springtime_di::instance_provider::TypedComponentInstanceProvider;
18use springtime_di::scope::PROTOTYPE;
19use springtime_di::scope::PrototypeScopeFactory;
20use springtime_di::scope::SINGLETON;
21use springtime_di::scope::SingletonScopeFactory;
22use std::any::TypeId;
23use std::sync::Arc;
24use std::sync::LazyLock;
25use std::sync::RwLock;
26
27pub static STATIC_COMPONENT_DEFINITION_REGISTRY_WRAPPER: LazyLock<Option<Arc<StaticComponentDefinitionRegistryWrapper>>> = LazyLock::new(|| {
28    StaticComponentDefinitionRegistry::new(true, &SimpleContextFactory)
29        .ok()
30        .map(|definition_registry| Arc::new(StaticComponentDefinitionRegistryWrapper::new(definition_registry)))
31});
32
33pub static SHARED_COMPONENT_DEFINITION_REGISTRY: LazyLock<Option<Box<SharedComponentDefinitionRegistry>>> = LazyLock::new(|| {
34    STATIC_COMPONENT_DEFINITION_REGISTRY_WRAPPER
35        .clone()
36        .map(|parent_definition_registry| Box::new(SharedComponentDefinitionRegistry::new(parent_definition_registry.clone())))
37});
38
39#[allow(clippy::let_and_return)]
40pub fn get_shared_component_definition_registry() -> Option<Box<SharedComponentDefinitionRegistry>> {
41    let shared_component_definition_registry = SHARED_COMPONENT_DEFINITION_REGISTRY.clone();
42    shared_component_definition_registry
43}
44
45pub fn get_shared_component_factory() -> ComponentFactory {
46    let Some(definition_registry) = get_shared_component_definition_registry() else {
47        panic!("Failed to initialize the shared component definition registry!");
48    };
49    ComponentFactory::new(
50        definition_registry,
51        [
52            (SINGLETON.to_string(), Box::<SingletonScopeFactory>::default() as ScopeFactoryPtr),
53            (PROTOTYPE.to_string(), Box::<PrototypeScopeFactory>::default() as ScopeFactoryPtr),
54        ]
55        .into_iter()
56        .collect(),
57    )
58}
59
60pub fn get_container<T>() -> Arc<T>
61where
62    T: Injectable + ?Sized + Send + Sync,
63{
64    let mut component_factory = get_shared_component_factory();
65    // match TypedComponentInstanceProvider::primary_instance_typed::<dyn Runtime + Send + Sync>(&mut component_factory) {
66    match TypedComponentInstanceProvider::primary_instance_typed::<T>(&mut component_factory) {
67        Ok(runtime) => runtime,
68        // Err(e) => {
69        //     panic!("{}", e);
70        // }
71        Err(ComponentInstanceProviderError::NoPrimaryInstance { type_id, type_name }) => {
72            error!("Missing component {type_name:?}");
73            let instances: Result<Vec<(ComponentInstanceAnyPtr, CastFunction)>, ComponentInstanceProviderError> = component_factory.instances(type_id);
74            match instances {
75                Ok(instances) => {
76                    error!("Component factory has {} instances of type {:?}", instances.len(), type_id);
77                    for (component_instance, _) in instances {
78                        error!("  Type Id: {:?}", component_instance.type_id());
79                    }
80                }
81                Err(e) => {
82                    error!("None. {e:?}");
83                }
84            }
85            panic!("Cannot find a primary instance for component '{type_id:?}/{type_name:?}' - either none or multiple exists without a primary marker.");
86        }
87        Err(ComponentInstanceProviderError::IncompatibleComponent { type_id, type_name }) => {
88            panic!("Tried to downcast component to incompatible type: {type_id:?}/{type_name}");
89        }
90        Err(ComponentInstanceProviderError::NoNamedInstance(type_name)) => {
91            panic!("Cannot find named component: {type_name}");
92        }
93        Err(ComponentInstanceProviderError::UnrecognizedScope(scope)) => {
94            panic!("Unrecognized scope: {scope}");
95        }
96        Err(ComponentInstanceProviderError::DependencyCycle { type_id, type_name }) => {
97            panic!("Detected dependency cycle for: {type_id:?}/{type_name:?}");
98        }
99        Err(ComponentInstanceProviderError::ConstructorError(constructor_error)) => {
100            panic!("Error in component constructor: {constructor_error}");
101        }
102    }
103}
104
105#[derive(Debug)]
106pub struct StaticComponentDefinitionRegistryWrapper {
107    pub definition_registry: RwLock<StaticComponentDefinitionRegistry>,
108}
109
110impl StaticComponentDefinitionRegistryWrapper {
111    pub fn new(definition_registry: StaticComponentDefinitionRegistry) -> Self {
112        Self {
113            definition_registry: RwLock::new(definition_registry),
114        }
115    }
116}
117
118#[derive(Clone, Debug)]
119pub struct SharedComponentDefinitionRegistry {
120    definition_registry: Arc<StaticComponentDefinitionRegistryWrapper>,
121}
122
123impl SharedComponentDefinitionRegistry {
124    pub fn new(definition_registry: Arc<StaticComponentDefinitionRegistryWrapper>) -> Self {
125        Self { definition_registry }
126    }
127}
128
129impl ComponentDefinitionRegistry for SharedComponentDefinitionRegistry {
130    #[inline]
131    fn register_component(&mut self, target: TypeId, target_name: &str, metadata: &ComponentMetadata) -> Result<(), ComponentDefinitionRegistryError> {
132        {
133            let mut parent_definition_registry = self.definition_registry.definition_registry.write().unwrap();
134            parent_definition_registry.register_component(target, target_name, metadata)
135        }
136    }
137
138    #[inline]
139    fn register_alias(
140        &mut self,
141        alias_type: TypeId,
142        target_type: TypeId,
143        alias_name: &str,
144        target_name: &str,
145        metadata: &ComponentAliasMetadata,
146    ) -> Result<(), ComponentDefinitionRegistryError> {
147        {
148            let mut parent_definition_registry = self.definition_registry.definition_registry.write().unwrap();
149            parent_definition_registry.register_alias(alias_type, target_type, alias_name, target_name, metadata)
150        }
151    }
152
153    #[inline]
154    fn components_by_type(&self, type_id: TypeId) -> Vec<ComponentDefinition> {
155        {
156            let parent_definition_registry = self.definition_registry.definition_registry.read().unwrap();
157            parent_definition_registry.components_by_type(type_id)
158        }
159    }
160
161    #[inline]
162    fn component_by_name(&self, name: &str, type_id: TypeId) -> Option<ComponentDefinition> {
163        {
164            let parent_definition_registry = self.definition_registry.definition_registry.read().unwrap();
165            parent_definition_registry.component_by_name(name, type_id)
166        }
167    }
168
169    #[inline]
170    fn primary_component(&self, type_id: TypeId) -> Option<ComponentDefinition> {
171        {
172            let parent_definition_registry = self.definition_registry.definition_registry.read().unwrap();
173            parent_definition_registry.primary_component(type_id)
174        }
175    }
176
177    #[inline]
178    fn is_registered(&self, type_id: TypeId) -> bool {
179        {
180            let parent_definition_registry = self.definition_registry.definition_registry.read().unwrap();
181            parent_definition_registry.is_registered(type_id)
182        }
183    }
184
185    #[inline]
186    fn is_name_registered(&self, name: &str) -> bool {
187        {
188            let parent_definition_registry = self.definition_registry.definition_registry.read().unwrap();
189            parent_definition_registry.is_name_registered(name)
190        }
191    }
192
193    #[inline]
194    fn all_definitions(&self) -> FxHashMap<TypeId, Vec<ComponentDefinition>> {
195        {
196            let parent_definition_registry = self.definition_registry.definition_registry.read().unwrap();
197            parent_definition_registry.all_definitions()
198        }
199    }
200}