1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::module::{ComponentMap, ParameterMap};
use crate::parameters::ComponentParameters;
use crate::Module;
use crate::{Component, HasProvider, Provider, ProviderFn};
use std::any::{type_name, TypeId};
use std::fmt::{self, Debug};
use std::sync::Arc;
pub struct ModuleBuildContext<M: Module> {
resolved_components: ComponentMap,
component_overrides: ComponentMap,
provider_overrides: ComponentMap,
parameters: ParameterMap,
submodules: M::Submodules,
resolve_chain: Vec<ResolveStep>,
}
#[derive(PartialEq)]
struct ResolveStep {
component_type_name: &'static str,
component_type_id: TypeId,
interface_type_name: &'static str,
interface_type_id: TypeId,
}
impl Debug for ResolveStep {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.component_type_name)
}
}
impl<M: Module> ModuleBuildContext<M> {
pub(crate) fn new(
parameters: ParameterMap,
component_overrides: ComponentMap,
provider_overrides: ComponentMap,
submodules: M::Submodules,
) -> Self {
ModuleBuildContext {
resolved_components: ComponentMap::new(),
component_overrides,
provider_overrides,
parameters,
submodules,
resolve_chain: Vec::new(),
}
}
pub(crate) fn build(mut self) -> M {
M::build(&mut self)
}
pub fn submodules(&self) -> &M::Submodules {
&self.submodules
}
pub fn build_component<C: Component<M>>(&mut self) -> Arc<C::Interface> {
self.component_overrides
.get::<Arc<C::Interface>>()
.or_else(|| self.resolved_components.get::<Arc<C::Interface>>())
.map(Arc::clone)
.unwrap_or_else(|| {
let step = ResolveStep {
component_type_name: type_name::<C>(),
component_type_id: TypeId::of::<C>(),
interface_type_name: type_name::<C::Interface>(),
interface_type_id: TypeId::of::<C::Interface>(),
};
if self.resolve_chain.contains(&step) {
panic!(
"Circular dependency detected while resolving {}. Resolution chain: {:?}",
step.interface_type_name, self.resolve_chain
);
}
self.resolve_chain.push(step);
let parameters = self
.parameters
.remove::<ComponentParameters<C, C::Parameters>>()
.unwrap_or_default();
let component = C::build(self, parameters.value);
let component = Arc::from(component);
self.resolved_components
.insert::<Arc<C::Interface>>(Arc::clone(&component));
self.resolve_chain.pop();
component
})
}
pub fn provider_fn<P: Provider<M>>(&self) -> Arc<ProviderFn<M, P::Interface>>
where
M: HasProvider<P::Interface>,
{
self.provider_overrides
.get::<Arc<ProviderFn<M, P::Interface>>>()
.map(Arc::clone)
.unwrap_or_else(|| Arc::new(Box::new(P::provide)))
}
}