elif_core/container/
phase6_demo.rs1use crate::container::binding::ServiceBinder;
9use crate::container::conventions::{
10 ServiceConventions, ServiceMetadata, ServiceRegistry as ConventionServiceRegistry,
11};
12use crate::container::debug::ContainerInspector;
13use crate::container::ioc_container::IocContainer;
14use crate::container::module::{ModuleRegistry, ServiceModule};
15use crate::container::scope::ServiceScope;
16use crate::container::visualization::{
17 DependencyVisualizer, VisualizationFormat, VisualizationStyle,
18};
19use crate::errors::CoreError;
20use std::sync::Arc;
21
22#[derive(Default)]
24pub struct UserService;
25
26impl UserService {
27 pub fn get_user(&self, _id: u32) -> String {
28 "Demo User".to_string()
29 }
30}
31
32#[derive(Default)]
34pub struct UserRepository;
35
36impl UserRepository {
37 pub fn find_user(&self, _id: u32) -> Option<String> {
38 Some("Repository User".to_string())
39 }
40}
41
42#[derive(Default)]
44pub struct AppLogger;
45
46impl AppLogger {
47 pub fn log(&self, message: &str) {
48 println!("[LOG] {}", message);
49 }
50}
51
52pub struct UserModule;
54
55impl ServiceModule for UserModule {
56 fn name(&self) -> &str {
57 "User Management Module"
58 }
59
60 fn description(&self) -> Option<&str> {
61 Some("Handles user-related services and operations")
62 }
63
64 fn version(&self) -> Option<&str> {
65 Some("1.0.0")
66 }
67
68 fn configure(&self, services: &mut crate::container::binding::ServiceBindings) {
69 services.bind::<UserService, UserService>();
71 services.bind::<UserRepository, UserRepository>();
72 }
73
74 fn depends_on(&self) -> Vec<crate::container::module::ModuleId> {
75 vec![]
76 }
77}
78
79pub struct CoreModule;
81
82impl ServiceModule for CoreModule {
83 fn name(&self) -> &str {
84 "Core Module"
85 }
86
87 fn description(&self) -> Option<&str> {
88 Some("Core application services")
89 }
90
91 fn configure(&self, services: &mut crate::container::binding::ServiceBindings) {
92 services.bind::<AppLogger, AppLogger>();
94 }
97}
98
99pub fn demo_phase6_features() -> Result<(), CoreError> {
101 println!("=== Phase 6 Demo: Developer Experience & Tooling ===");
102 println!();
103
104 println!("1. Auto-wiring Conventions:");
106 println!("---------------------------");
107
108 let mut conventions = ServiceConventions::new();
109 conventions.add_naming_convention("*Service", ServiceScope::Singleton);
110 conventions.add_naming_convention("*Repository", ServiceScope::Scoped);
111 conventions.add_naming_convention("*Logger", ServiceScope::Singleton);
112
113 println!(
114 "✓ UserService lifetime: {:?}",
115 conventions.get_lifetime_for_type("UserService")
116 );
117 println!(
118 "✓ UserRepository lifetime: {:?}",
119 conventions.get_lifetime_for_type("UserRepository")
120 );
121 println!(
122 "✓ AppLogger lifetime: {:?}",
123 conventions.get_lifetime_for_type("AppLogger")
124 );
125
126 let mut service_registry = ConventionServiceRegistry::new();
128
129 let user_service_metadata =
130 ServiceMetadata::new("UserService".to_string()).with_lifetime(ServiceScope::Singleton);
131 service_registry.register_service(user_service_metadata);
132
133 let user_repo_metadata =
134 ServiceMetadata::new("UserRepository".to_string()).with_lifetime(ServiceScope::Scoped);
135 service_registry.register_service(user_repo_metadata);
136
137 println!(
138 "✓ Registered {} services with conventions",
139 service_registry.all_services().len()
140 );
141 println!();
142
143 println!("2. Module System:");
145 println!("-----------------");
146
147 let mut module_registry = ModuleRegistry::new();
148
149 module_registry.register_module(CoreModule, None)?;
151 module_registry.register_module(UserModule, None)?;
152
153 let load_order = module_registry.calculate_load_order()?;
155 println!(
156 "✓ Module load order calculated: {} modules",
157 load_order.len()
158 );
159
160 for (i, module_id) in load_order.iter().enumerate() {
161 if let Some(loaded_module) = module_registry.get_loaded_module(module_id) {
162 println!(
163 " {}. {} ({})",
164 i + 1,
165 loaded_module.metadata.name,
166 loaded_module
167 .metadata
168 .version
169 .as_deref()
170 .unwrap_or("no version")
171 );
172 }
173 }
174 println!();
175
176 println!("3. Debug & Inspection Tools:");
178 println!("-----------------------------");
179
180 let container = IocContainer::new();
181 let inspector = ContainerInspector::new(Arc::new(container));
182
183 let container_info = inspector.get_container_info();
184 println!(
185 "✓ Container Status: {}",
186 if container_info.is_built {
187 "Built"
188 } else {
189 "Not Built"
190 }
191 );
192 println!("✓ Registered Services: {}", container_info.service_count);
193 println!("✓ Cached Instances: {}", container_info.cached_instances);
194 println!();
195
196 println!("4. Dependency Visualization:");
198 println!("----------------------------");
199
200 let descriptors = vec![]; let visualizer = DependencyVisualizer::new(descriptors);
203
204 let style = VisualizationStyle::default();
206
207 match visualizer.visualize(VisualizationFormat::Ascii, style.clone()) {
208 Ok(ascii_viz) => {
209 println!("✓ ASCII Visualization Generated:");
210 println!(
211 "{}",
212 ascii_viz.lines().take(10).collect::<Vec<_>>().join("\n")
213 );
214 if ascii_viz.lines().count() > 10 {
215 println!(" ... (truncated)");
216 }
217 }
218 Err(e) => println!("⚠️ ASCII visualization failed: {}", e),
219 }
220 println!();
221
222 match visualizer.visualize(VisualizationFormat::Json, style) {
223 Ok(json_viz) => {
224 println!("✓ JSON Visualization Generated ({} bytes)", json_viz.len());
225 let preview: String = json_viz.chars().take(200).collect();
227 println!(" Preview: {}...", preview);
228 }
229 Err(e) => println!("⚠️ JSON visualization failed: {}", e),
230 }
231 println!();
232
233 println!("5. Container Health Monitoring:");
235 println!("-------------------------------");
236
237 println!("✓ Health Check System Available");
239 println!("✓ Performance Profiler Available");
240 println!("✓ Resolution Tracer Available");
241 println!();
242
243 println!("🎉 Phase 6 Demo Complete!");
244 println!(" All developer experience and tooling features are operational.");
245
246 Ok(())
247}
248
249#[cfg(test)]
250mod tests {
251 use super::*;
252
253 #[test]
254 fn test_phase6_demo() {
255 let result = demo_phase6_features();
256 assert!(result.is_ok(), "Phase 6 demo should run successfully");
257 }
258
259 #[test]
260 fn test_service_conventions() {
261 let conventions = ServiceConventions::new();
262
263 assert_eq!(
265 conventions.get_lifetime_for_type("UserService"),
266 ServiceScope::Singleton
267 );
268 assert_eq!(
269 conventions.get_lifetime_for_type("UserRepository"),
270 ServiceScope::Scoped
271 );
272 assert_eq!(
273 conventions.get_lifetime_for_type("PaymentFactory"),
274 ServiceScope::Transient
275 );
276 assert_eq!(
277 conventions.get_lifetime_for_type("AppLogger"),
278 ServiceScope::Singleton
279 );
280 }
281
282 #[test]
283 fn test_module_registry() {
284 let mut registry = ModuleRegistry::new();
285
286 assert!(registry.register_module(CoreModule, None).is_ok());
288 assert!(registry.register_module(UserModule, None).is_ok());
289
290 let load_order = registry.calculate_load_order();
292 assert!(load_order.is_ok());
293 assert_eq!(load_order.unwrap().len(), 2);
294 }
295
296 #[test]
297 fn test_container_inspector() {
298 let container = IocContainer::new();
299 let inspector = ContainerInspector::new(Arc::new(container));
300
301 let info = inspector.get_container_info();
302 assert!(!info.is_built); assert_eq!(info.service_count, 0); }
305
306 #[test]
307 fn test_service_metadata() {
308 let metadata = ServiceMetadata::new("TestService".to_string())
309 .with_lifetime(ServiceScope::Singleton)
310 .with_name("test".to_string())
311 .as_default()
312 .with_tag("core".to_string());
313
314 assert_eq!(metadata.type_name, "TestService");
315 assert_eq!(metadata.lifetime, Some(ServiceScope::Singleton));
316 assert_eq!(metadata.name, Some("test".to_string()));
317 assert!(metadata.is_default);
318 assert_eq!(metadata.tags, vec!["core"]);
319 }
320}