allsource_core/infrastructure/di/
builder.rs1use super::ServiceContainer;
7use crate::{
8 application::services::consumer::ConsumerRegistry,
9 domain::repositories::{
10 AccessTokenRepository, ArticleRepository, AuditEventRepository, CreatorRepository,
11 EventStreamRepository, ForkRepository, TenantRepository, TransactionRepository,
12 },
13 infrastructure::{
14 persistence::{SystemMetadataStore, SystemRepositories},
15 repositories::{
16 EventSourcedConfigRepository, InMemoryAccessTokenRepository, InMemoryArticleRepository,
17 InMemoryCreatorRepository, InMemoryEventStreamRepository, InMemoryForkRepository,
18 InMemoryTransactionRepository,
19 },
20 },
21};
22use std::sync::Arc;
23
24#[derive(Default)]
45pub struct ContainerBuilder {
46 creator_repository: Option<Arc<dyn CreatorRepository>>,
47 article_repository: Option<Arc<dyn ArticleRepository>>,
48 transaction_repository: Option<Arc<dyn TransactionRepository>>,
49 access_token_repository: Option<Arc<dyn AccessTokenRepository>>,
50 fork_repository: Option<Arc<dyn ForkRepository>>,
51 event_stream_repository: Option<Arc<dyn EventStreamRepository>>,
52
53 tenant_repository: Option<Arc<dyn TenantRepository>>,
55 audit_repository: Option<Arc<dyn AuditEventRepository>>,
56 config_repository: Option<Arc<EventSourcedConfigRepository>>,
57 system_store: Option<Arc<SystemMetadataStore>>,
58 consumer_registry: Option<Arc<ConsumerRegistry>>,
59}
60
61impl ContainerBuilder {
62 pub fn new() -> Self {
64 Self::default()
65 }
66
67 pub fn with_in_memory_repositories(mut self) -> Self {
72 self.creator_repository = Some(Arc::new(InMemoryCreatorRepository::new()));
73 self.article_repository = Some(Arc::new(InMemoryArticleRepository::new()));
74 self.transaction_repository = Some(Arc::new(InMemoryTransactionRepository::new()));
75 self.access_token_repository = Some(Arc::new(InMemoryAccessTokenRepository::new()));
76 self.fork_repository = Some(Arc::new(InMemoryForkRepository::new()));
77 self.event_stream_repository = Some(Arc::new(InMemoryEventStreamRepository::new()));
78 self
79 }
80
81 pub fn with_creator_repository(mut self, repository: Arc<dyn CreatorRepository>) -> Self {
83 self.creator_repository = Some(repository);
84 self
85 }
86
87 pub fn with_article_repository(mut self, repository: Arc<dyn ArticleRepository>) -> Self {
89 self.article_repository = Some(repository);
90 self
91 }
92
93 pub fn with_transaction_repository(
95 mut self,
96 repository: Arc<dyn TransactionRepository>,
97 ) -> Self {
98 self.transaction_repository = Some(repository);
99 self
100 }
101
102 pub fn with_access_token_repository(
104 mut self,
105 repository: Arc<dyn AccessTokenRepository>,
106 ) -> Self {
107 self.access_token_repository = Some(repository);
108 self
109 }
110
111 pub fn with_fork_repository(mut self, repository: Arc<dyn ForkRepository>) -> Self {
113 self.fork_repository = Some(repository);
114 self
115 }
116
117 pub fn with_event_stream_repository(
119 mut self,
120 repository: Arc<dyn EventStreamRepository>,
121 ) -> Self {
122 self.event_stream_repository = Some(repository);
123 self
124 }
125
126 pub fn with_system_repositories(mut self, repos: SystemRepositories) -> Self {
134 self.system_store = Some(repos.system_store);
135 self.tenant_repository = Some(repos.tenant_repository);
136 self.audit_repository = Some(repos.audit_repository);
137 self.config_repository = Some(repos.config_repository);
138 self.consumer_registry = Some(repos.consumer_registry);
139 self
140 }
141
142 pub fn with_tenant_repository(mut self, repository: Arc<dyn TenantRepository>) -> Self {
144 self.tenant_repository = Some(repository);
145 self
146 }
147
148 pub fn with_audit_repository(mut self, repository: Arc<dyn AuditEventRepository>) -> Self {
150 self.audit_repository = Some(repository);
151 self
152 }
153
154 pub fn build(self) -> ServiceContainer {
162 let mut container = ServiceContainer::new(
163 self.creator_repository
164 .expect("CreatorRepository not configured. Use with_in_memory_repositories() or with_creator_repository()"),
165 self.article_repository
166 .expect("ArticleRepository not configured. Use with_in_memory_repositories() or with_article_repository()"),
167 self.transaction_repository
168 .expect("TransactionRepository not configured. Use with_in_memory_repositories() or with_transaction_repository()"),
169 self.access_token_repository
170 .expect("AccessTokenRepository not configured. Use with_in_memory_repositories() or with_access_token_repository()"),
171 self.fork_repository
172 .expect("ForkRepository not configured. Use with_in_memory_repositories() or with_fork_repository()"),
173 self.event_stream_repository
174 .expect("EventStreamRepository not configured. Use with_in_memory_repositories() or with_event_stream_repository()"),
175 );
176
177 container.tenant_repository = self.tenant_repository;
178 container.audit_repository = self.audit_repository;
179 container.config_repository = self.config_repository;
180 container.system_store = self.system_store;
181 container.consumer_registry = self.consumer_registry;
182
183 container
184 }
185
186 pub fn try_build(self) -> Result<ServiceContainer, ContainerBuilderError> {
190 let mut container = ServiceContainer::new(
191 self.creator_repository
192 .ok_or(ContainerBuilderError::MissingRepository(
193 "CreatorRepository",
194 ))?,
195 self.article_repository
196 .ok_or(ContainerBuilderError::MissingRepository(
197 "ArticleRepository",
198 ))?,
199 self.transaction_repository
200 .ok_or(ContainerBuilderError::MissingRepository(
201 "TransactionRepository",
202 ))?,
203 self.access_token_repository
204 .ok_or(ContainerBuilderError::MissingRepository(
205 "AccessTokenRepository",
206 ))?,
207 self.fork_repository
208 .ok_or(ContainerBuilderError::MissingRepository("ForkRepository"))?,
209 self.event_stream_repository
210 .ok_or(ContainerBuilderError::MissingRepository(
211 "EventStreamRepository",
212 ))?,
213 );
214
215 container.tenant_repository = self.tenant_repository;
216 container.audit_repository = self.audit_repository;
217 container.config_repository = self.config_repository;
218 container.system_store = self.system_store;
219 container.consumer_registry = self.consumer_registry;
220
221 Ok(container)
222 }
223}
224
225#[derive(Debug, Clone)]
227pub enum ContainerBuilderError {
228 MissingRepository(&'static str),
230}
231
232impl std::fmt::Display for ContainerBuilderError {
233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234 match self {
235 ContainerBuilderError::MissingRepository(name) => {
236 write!(f, "{name} not configured")
237 }
238 }
239 }
240}
241
242impl std::error::Error for ContainerBuilderError {}