1use crate::event::{ContainerLifecycleEvent, LifecycleEventPublisher};
9use crate::{ComponentDefinition, ComponentFactory, ComponentInstance, ComponentScope};
10use dashmap::{DashMap, DashSet};
11use std::any::{Any, TypeId};
12use std::collections::HashMap;
13use std::sync::Arc;
14use std::time::Instant;
15use verdure_core::error::container::ContainerError;
16
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
36pub struct ComponentDescriptor {
37 pub type_id: TypeId,
39 pub qualifier: Option<&'static str>,
41}
42
43impl ComponentDescriptor {
44 pub fn new(type_id: TypeId, qualifier: Option<&'static str>) -> Self {
51 Self { type_id, qualifier }
52 }
53
54 pub fn for_type<T: 'static>() -> Self {
60 Self {
61 type_id: TypeId::of::<T>(),
62 qualifier: None,
63 }
64 }
65
66 pub fn with_qualifier<T: 'static>(qualifier: &'static str) -> Self {
76 Self {
77 type_id: TypeId::of::<T>(),
78 qualifier: Some(qualifier),
79 }
80 }
81}
82
83#[derive(Debug, Default, Clone)]
88pub struct ComponentStats {
89 pub created_at: Option<Instant>,
91 pub last_accessed: Option<Instant>,
93 pub access_count: u64,
95 pub creation_time: u64,
97}
98
99pub struct ComponentContainer {
146 components: DashMap<ComponentDescriptor, ComponentInstance>,
148 initializing: DashSet<TypeId>,
150 stats: DashMap<ComponentDescriptor, ComponentStats>,
152 lifecycle_publisher: Arc<LifecycleEventPublisher>,
154}
155
156impl ComponentContainer {
157 pub fn new() -> Self {
167 Self {
168 components: DashMap::new(),
169 initializing: DashSet::new(),
170 stats: DashMap::new(),
171 lifecycle_publisher: Arc::new(LifecycleEventPublisher::new()),
172 }
173 }
174
175 pub fn initialize(&self) -> Result<(), ContainerError> {
198 let component_count = inventory::iter::<ComponentDefinition>().count();
199
200 self.lifecycle_publisher
201 .publish(&ContainerLifecycleEvent::InitializationStarted {
202 container: self,
203 component_count,
204 });
205
206 let start_time = Instant::now();
207
208 let mut def_map = HashMap::new();
209 for def in inventory::iter::<ComponentDefinition> {
210 let type_id = (def.type_id)();
211 def_map.insert(type_id, def);
212 }
213
214 for def in inventory::iter::<ComponentDefinition> {
215 let type_id = (def.type_id)();
216 let descriptor = ComponentDescriptor::new(type_id, None);
217
218 if !self.components.contains_key(&descriptor) {
219 self.resolve_bean(&descriptor, &def_map)?;
220 } else {
221 }
223 }
224
225 self.lifecycle_publisher
226 .publish(&ContainerLifecycleEvent::InitializationCompleted {
227 container: self,
228 component_count: self.components.len(),
229 duration: start_time.elapsed(),
230 });
231
232 Ok(())
233 }
234
235 pub fn register_component(&self, instance: ComponentInstance) {
263 let type_id = (*instance).type_id();
264 self.register_component_by_type_id(type_id, instance);
265 }
266
267 pub fn register_component_by_type_id(&self, type_id: TypeId, instance: ComponentInstance) {
277 let descriptor = ComponentDescriptor::new(type_id, None);
278 self.components.insert(descriptor, instance);
279 }
280
281 fn resolve_bean(
282 &self,
283 descriptor: &ComponentDescriptor,
284 def_map: &HashMap<TypeId, &ComponentDefinition>,
285 ) -> Result<ComponentInstance, ContainerError> {
286 if !self.initializing.insert(descriptor.type_id) {
287 let type_name = def_map
288 .get(&descriptor.type_id)
289 .map_or("Unknown", |d| d.type_name);
290 return Err(ContainerError::circular_dependency(format!(
291 "{}",
292 type_name
293 )));
294 }
295
296 let def = match def_map.get(&descriptor.type_id) {
297 Some(d) => *d,
298 None => {
299 self.initializing.remove(&descriptor.type_id);
300 return Err(ContainerError::not_found(format!(
301 "Bean definition not found for type ID {:?}",
302 descriptor.type_id
303 )));
304 }
305 };
306
307 let dependencies = (def.dependencies)();
308 let mut deps_map = HashMap::new();
309 for dep_id in dependencies {
310 let dep_descriptor = ComponentDescriptor::new(dep_id, None);
311
312 if let Some(instance) = self.components.get(&dep_descriptor) {
314 deps_map.insert(dep_id, instance.clone());
315 continue;
316 }
317
318 if let Some(_dep_def) = def_map.get(&dep_id) {
319 let dep_instance = self.resolve_bean(&dep_descriptor, def_map)?;
320 deps_map.insert(dep_id, dep_instance);
321 } else {
322 self.initializing.remove(&descriptor.type_id);
323 return Err(ContainerError::not_found(format!(
324 "Dependency not found for type ID {:?}",
325 dep_id
326 )));
327 }
328 }
329
330 let start = Instant::now();
331 let instance = match (def.creator)(deps_map) {
332 Ok(i) => i,
333 Err(e) => {
334 self.initializing.remove(&descriptor.type_id);
335 return Err(ContainerError::creation_failed(format!(
336 "Failed to create bean '{}': '{}'",
337 def.type_name, e
338 )));
339 }
340 };
341 let creation_time = start.elapsed();
342
343 self.lifecycle_publisher
344 .publish(&ContainerLifecycleEvent::ComponentCreated {
345 container: self,
346 component_name: def.type_name,
347 component_type_id: descriptor.type_id,
348 creation_duration: creation_time,
349 });
350
351 self.initializing.remove(&descriptor.type_id);
352
353 match (def.scope)() {
354 ComponentScope::Singleton => {
355 self.components.insert(descriptor.clone(), instance.clone());
356 }
357 _ => {}
358 };
359
360 self.stats.insert(
361 descriptor.clone(),
362 ComponentStats {
363 created_at: Some(Instant::now()),
364 last_accessed: Some(Instant::now()),
365 access_count: 1,
366 creation_time: creation_time.as_millis() as u64,
367 },
368 );
369
370 Ok(instance)
371 }
372}
373
374impl ComponentFactory for ComponentContainer {
375 fn get_component_by_type_id(&self, type_id: TypeId) -> Option<Arc<dyn Any + Send + Sync>> {
376 Some(
377 self.components
378 .get(&ComponentDescriptor::new(type_id, None))?
379 .clone(),
380 )
381 }
382
383 fn get_component<T: Any + Send + Sync>(&self) -> Option<Arc<T>> {
384 let component_any = self.get_component_by_type_id(TypeId::of::<T>())?;
385 component_any.downcast().ok()
386 }
387}
388
389#[cfg(test)]
390mod tests {
391 use super::*;
392 use crate::ComponentInitializer;
393 use std::sync::atomic::{AtomicU32, Ordering};
394
395 #[derive(Debug)]
396 struct TestComponent {
397 value: u32,
398 }
399
400 impl TestComponent {
401 fn new(value: u32) -> Self {
402 Self { value }
403 }
404 }
405
406 #[derive(Debug)]
407 struct TestComponentWithDeps {
408 dependency: Arc<TestComponent>,
409 value: String,
410 }
411
412 static CREATION_COUNTER: AtomicU32 = AtomicU32::new(0);
413
414 impl ComponentInitializer for TestComponent {
415 type Dependencies = ();
416
417 fn __new(_deps: Self::Dependencies) -> Self {
418 CREATION_COUNTER.fetch_add(1, Ordering::SeqCst);
419 TestComponent::new(42)
420 }
421
422 fn __scope() -> crate::ComponentScope {
423 crate::ComponentScope::Singleton
424 }
425 }
426
427 impl ComponentInitializer for TestComponentWithDeps {
428 type Dependencies = (Arc<TestComponent>,);
429
430 fn __new(deps: Self::Dependencies) -> Self {
431 let (dependency,) = deps;
432 TestComponentWithDeps {
433 dependency,
434 value: "test".to_string(),
435 }
436 }
437
438 fn __scope() -> crate::ComponentScope {
439 crate::ComponentScope::Singleton
440 }
441 }
442
443 #[test]
444 fn test_component_descriptor() {
445 let desc1 = ComponentDescriptor::for_type::<TestComponent>();
446 let desc2 = ComponentDescriptor::new(TypeId::of::<TestComponent>(), None);
447 assert_eq!(desc1, desc2);
448
449 let desc_with_qualifier = ComponentDescriptor::with_qualifier::<TestComponent>("test");
450 assert_ne!(desc1, desc_with_qualifier);
451 assert_eq!(desc_with_qualifier.qualifier, Some("test"));
452 }
453
454 #[test]
455 fn test_container_creation() {
456 let container = ComponentContainer::new();
457 assert!(container.components.is_empty());
458 assert!(container.initializing.is_empty());
459 assert!(container.stats.is_empty());
460 }
461
462 #[test]
463 fn test_manual_component_registration() {
464 let container = ComponentContainer::new();
465 let test_component = Arc::new(TestComponent::new(100));
466
467 container.register_component(test_component.clone());
468
469 let retrieved: Option<Arc<TestComponent>> = container.get_component();
470 assert!(retrieved.is_some());
471 assert_eq!(retrieved.unwrap().value, 100);
472 }
473
474 #[test]
475 fn test_register_component_by_type_id() {
476 let container = ComponentContainer::new();
477 let test_component = Arc::new(TestComponent::new(200));
478 let type_id = TypeId::of::<TestComponent>();
479
480 container.register_component_by_type_id(type_id, test_component);
481
482 let retrieved = container.get_component_by_type_id(type_id);
483 assert!(retrieved.is_some());
484
485 let downcast_component: Result<Arc<TestComponent>, _> = retrieved.unwrap().downcast();
486 assert!(downcast_component.is_ok());
487 assert_eq!(downcast_component.unwrap().value, 200);
488 }
489
490 #[test]
491 fn test_get_nonexistent_component() {
492 let container = ComponentContainer::new();
493 let result: Option<Arc<TestComponent>> = container.get_component();
494 assert!(result.is_none());
495 }
496
497 #[test]
498 fn test_component_stats_default() {
499 let stats = ComponentStats::default();
500 assert!(stats.created_at.is_none());
501 assert!(stats.last_accessed.is_none());
502 assert_eq!(stats.access_count, 0);
503 assert_eq!(stats.creation_time, 0);
504 }
505
506 #[test]
507 fn test_component_descriptor_hash_and_eq() {
508 let desc1 = ComponentDescriptor::for_type::<TestComponent>();
509 let desc2 = ComponentDescriptor::for_type::<TestComponent>();
510 let desc3 = ComponentDescriptor::with_qualifier::<TestComponent>("test");
511
512 assert_eq!(desc1, desc2);
513 assert_ne!(desc1, desc3);
514
515 let mut map = std::collections::HashMap::new();
517 map.insert(desc1.clone(), "value1");
518 map.insert(desc3.clone(), "value2");
519
520 assert_eq!(map.get(&desc2), Some(&"value1"));
521 assert_eq!(map.get(&desc3), Some(&"value2"));
522 }
523}