luminos_container/
container.rs1use 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}