elif_core/container/
container.rs

1use crate::foundation::traits::Service;
2use crate::container::registry::ServiceRegistry;
3use crate::container::scope::ServiceScope;
4use crate::errors::CoreError;
5use service_builder::builder;
6use std::any::TypeId;
7use std::sync::Arc;
8
9/// Main dependency injection container
10#[builder]
11pub struct Container {
12    #[builder(getter, setter)]
13    registry: ServiceRegistry,
14    
15    #[builder(getter, setter)]
16    scope: ServiceScope,
17    
18    #[builder(default)]
19    initialized: bool,
20}
21
22impl Container {
23    /// Create a new container with default registry and scope
24    pub fn new() -> Self {
25        ContainerBuilder::new()
26            .registry(ServiceRegistry::new())
27            .scope(ServiceScope::Singleton)
28            .build_with_defaults().expect("Failed to build container")
29    }
30    
31    /// Register a service in the container
32    pub fn register<T>(&mut self, service: T) -> Result<(), CoreError>
33    where
34        T: Service + Clone + 'static,
35    {
36        self.registry.register_service(service)
37    }
38    
39    /// Register a singleton service
40    pub fn register_singleton<T>(&mut self, service: T) -> Result<(), CoreError>
41    where
42        T: Service + Clone + 'static,
43    {
44        self.registry.register_singleton(service)
45    }
46    
47    /// Register a transient service
48    pub fn register_transient<T>(&mut self, factory: Box<dyn Fn() -> T + Send + Sync>) -> Result<(), CoreError>
49    where
50        T: Service + 'static,
51    {
52        self.registry.register_transient(factory)
53    }
54    
55    /// Resolve a service from the container
56    pub fn resolve<T>(&self) -> Result<Arc<T>, CoreError>
57    where
58        T: Service + Clone + 'static,
59    {
60        self.registry.resolve::<T>()
61    }
62    
63    /// Try to resolve a service, returning None if not found
64    pub fn try_resolve<T>(&self) -> Option<Arc<T>>
65    where
66        T: Service + Clone + 'static,
67    {
68        self.registry.try_resolve::<T>()
69    }
70    
71    /// Check if a service is registered
72    pub fn contains<T>(&self) -> bool
73    where
74        T: Service + 'static,
75    {
76        self.registry.contains::<T>()
77    }
78    
79    /// Check if the container is properly configured
80    pub fn validate(&self) -> Result<(), CoreError> {
81        self.registry.validate()
82    }
83    
84    /// Initialize the container and all its services
85    pub async fn initialize(&mut self) -> Result<(), CoreError> {
86        if self.initialized {
87            return Ok(());
88        }
89        
90        self.registry.initialize_all().await?;
91        self.initialized = true;
92        Ok(())
93    }
94    
95    /// Check if the container is initialized
96    pub fn is_initialized(&self) -> bool {
97        self.initialized
98    }
99    
100    /// Get the number of registered services
101    pub fn service_count(&self) -> usize {
102        self.registry.service_count()
103    }
104    
105    /// Get a list of all registered service types
106    pub fn registered_services(&self) -> Vec<TypeId> {
107        self.registry.registered_services()
108    }
109}
110
111impl Default for Container {
112    fn default() -> Self {
113        Self::new()
114    }
115}
116
117impl std::fmt::Debug for Container {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        f.debug_struct("Container")
120            .field("service_count", &self.service_count())
121            .field("initialized", &self.initialized)
122            .field("scope", &self.scope)
123            .finish()
124    }
125}