luminos_container/
container.rs

1use std::any::{Any, TypeId};
2use std::collections::HashMap;
3use std::sync::{Arc, Mutex};
4use luminos_contracts::container::{Injectable, Contract};
5use luminos_contracts::support::ServiceProvider;
6
7type Factory = Arc<dyn Fn(&Container) -> Arc<dyn Any + Send + Sync> + Send + Sync>;
8
9#[derive(Default)]
10pub struct Container {
11    instances: Mutex<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>,
12    factories: Mutex<HashMap<TypeId, Factory>>,
13    providers: Mutex<Vec<Box<dyn ServiceProvider<Container>>>>
14}
15
16impl Container {
17    pub fn new() -> Self {
18        Self {
19            instances: Mutex::new(HashMap::new()),
20            factories: Mutex::new(HashMap::new()),
21            providers: Mutex::new(Vec::new()),
22        }
23    }
24}
25
26impl Contract for Container {
27    fn bind<T, F>(&self, factory: F)
28    where
29        T: Sized + Send + Sync + 'static,
30        F: Fn(&Container) -> Arc<T> + Send + Sync + 'static,
31    {
32        let type_id = TypeId::of::<T>(); 
33        let boxed_factory: Factory =
34            Arc::new(move |c| factory(c) as Arc<dyn Any + Send + Sync>);
35        self.factories.lock().unwrap().insert(type_id, boxed_factory);
36    }
37
38
39    fn resolve<T>(&self) -> Arc<T>
40    where
41        T: Injectable + Send + Sync + 'static,
42    {
43        let type_id = TypeId::of::<T>();
44        
45        if let Some(inst) = self.instances.lock().unwrap().get(&type_id) {
46            return inst.clone().downcast::<T>().unwrap();
47        }
48        
49        {
50            let factories = self.factories.lock().unwrap();
51            if let Some(factory) = factories.get(&type_id) {
52                let factory = factory.clone();
53                drop(factories); 
54                
55                let built = factory(self);
56                self.instances.lock().unwrap().insert(type_id, built.clone());
57                return built.downcast::<T>().unwrap();
58            }
59        }
60        
61        T::__register(self);
62        
63        let factories = self.factories.lock().unwrap();
64        if let Some(factory) = factories.get(&type_id) {
65            let factory = factory.clone();
66            drop(factories);
67            
68            let built = factory(self);
69            self.instances.lock().unwrap().insert(type_id, built.clone());
70            return built.downcast::<T>().unwrap();
71        }
72        
73        panic!("Failed to resolve type: {:?}", std::any::type_name::<T>());
74    }
75
76    fn add_provider(&self, provider: Box<dyn ServiceProvider<Self> + 'static>) -> &Self {
77        self.providers.lock().unwrap().push(provider);
78        self
79    }
80
81    fn add_providers(&self, providers: Vec<Box<dyn ServiceProvider<Container>>>) -> &Self
82    {
83        for provider in providers {
84            self.add_provider(provider);
85        }
86
87        self
88    }
89
90    fn boot(&self) -> &Self
91    {
92        let providers = self.providers.lock().unwrap();
93        
94        for provider in providers.iter() {
95            provider.register(self);
96        }
97        
98        for provider in providers.iter() {
99            provider.boot(self);
100        }
101        
102        self
103    }
104
105    fn with_provider(self, provider: Box<dyn ServiceProvider<Self> + 'static>) -> Self {
106        self.add_provider(provider);
107        self
108    }
109
110    fn build(&self) -> &Self
111    {
112        self.boot()
113    }
114}