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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
use super::*;
#[cfg(feature = "thread-safe")]
pub trait Module: Send + Sync {
/// Returns the unique type identifier for this module.
///
/// This method provides runtime type identification for modules, which can be useful
/// for debugging, logging, or implementing module deduplication logic.
///
/// # Returns
///
/// A [`TypeId`](std::any::TypeId) that uniquely identifies the concrete type of this module.
///
/// # Examples
///
/// ```
/// use fluxdi::module::Module;
/// use fluxdi::injector::Injector;
/// use std::any::TypeId;
///
/// struct MyModule;
/// impl Module for MyModule {
/// fn providers(&self, injector: &Injector) {}
/// }
///
/// let module = MyModule;
/// let type_id = module.type_id();
/// assert_eq!(type_id, TypeId::of::<MyModule>());
/// ```
fn type_id(&self) -> std::any::TypeId
where
Self: 'static,
{
std::any::TypeId::of::<Self>()
}
/// Returns the type name of this module as a string.
///
/// This method provides a human-readable representation of the module's type,
/// which is particularly useful for debugging, logging, and error messages.
///
/// # Returns
///
/// A static string slice containing the fully-qualified type name of this module.
///
/// # Examples
///
/// ```
/// use fluxdi::module::Module;
/// use fluxdi::injector::Injector;
///
/// struct DatabaseModule;
/// impl Module for DatabaseModule {
/// fn providers(&self, injector: &Injector) {}
/// }
///
/// let module = DatabaseModule;
/// let name = module.type_name();
/// // The exact format depends on the module path
/// assert!(name.contains("DatabaseModule"));
/// ```
fn type_name(&self) -> &'static str
where
Self: 'static,
{
std::any::type_name::<Self>()
}
/// Returns a list of modules that this module imports.
///
/// Imported modules have their providers registered before this module's providers.
/// This allows a module to build upon functionality provided by other modules.
///
/// # Default Implementation
///
/// By default, returns an empty vector (no imports).
///
/// # Returns
///
/// A vector of boxed `Module` trait objects representing the imported modules.
///
/// # Examples
///
/// ```
/// use fluxdi::module::Module;
/// use fluxdi::injector::Injector;
///
/// struct CoreModule;
/// impl Module for CoreModule {
/// fn providers(&self, injector: &Injector) {}
/// }
///
/// struct FeatureModule;
/// impl Module for FeatureModule {
/// fn imports(&self) -> Vec<Box<dyn Module>> {
/// vec![Box::new(CoreModule)]
/// }
///
/// fn providers(&self, injector: &Injector) {}
/// }
/// ```
fn imports(&self) -> Vec<Box<dyn Module>> {
vec![]
}
/// Configures providers for this module.
///
/// This is the preferred registration hook used by `Application` bootstrap flows.
/// The default implementation delegates to [`providers`](Module::providers) for
/// backward compatibility.
fn configure(&self, injector: &Injector) -> Result<(), Error> {
self.providers(injector);
Ok(())
}
/// Registers providers with the given injector.
///
/// This method is called to configure the dependency injection container with
/// the services that this module provides. Use the injector to register
/// factories, values, and other providers.
///
/// # Parameters
///
/// - `injector`: The injector instance to register providers with
///
/// # Examples
///
/// ```
/// use fluxdi::module::Module;
/// use fluxdi::injector::Injector;
///
/// struct MyModule;
///
/// impl Module for MyModule {
/// fn providers(&self, injector: &Injector) {
/// // Register providers here
/// // injector.register<...>(...)
/// }
/// }
/// ```
fn providers(&self, _injector: &Injector) {}
/// Async variant of provider registration.
///
/// Default behavior calls [`providers`](Module::providers) synchronously.
fn providers_async(&self, injector: Shared<Injector>) -> ModuleLifecycleFuture {
let result = self.configure(&injector);
Box::pin(async move { result })
}
/// Lifecycle hook executed after this module and its imports finish registration.
fn on_start(&self, _injector: Shared<Injector>) -> ModuleLifecycleFuture {
Box::pin(async { Ok(()) })
}
/// Lifecycle hook executed during application shutdown in reverse module order.
fn on_stop(&self, _injector: Shared<Injector>) -> ModuleLifecycleFuture {
Box::pin(async { Ok(()) })
}
}