0
# Aliases and Names
1
2
Convention-based service registration and resolution using string names and aliases instead of type annotations. This approach enables flexible service registration patterns and runtime service resolution by name.
3
4
## Capabilities
5
6
### Single Alias Registration
7
8
Register a single name-to-type mapping for convention-based service resolution.
9
10
```python { .api }
11
def add_alias(self, name: str, desired_type: Type) -> Container:
12
"""
13
Add a single alias mapping name to type.
14
15
Args:
16
name: String name/alias for the service
17
desired_type: Type to associate with the name
18
19
Returns:
20
Container instance for method chaining
21
22
Raises:
23
AliasAlreadyDefined: If alias already exists
24
"""
25
```
26
27
### Multiple Aliases Registration
28
29
Register multiple name-to-type mappings at once using a dictionary.
30
31
```python { .api }
32
def add_aliases(self, values: AliasesTypeHint) -> Container:
33
"""
34
Add multiple alias mappings from a dictionary.
35
36
Args:
37
values: Dictionary mapping names to types
38
39
Returns:
40
Container instance for method chaining
41
42
Raises:
43
AliasAlreadyDefined: If any alias already exists
44
"""
45
```
46
47
### Single Alias Setting (Override)
48
49
Set a single alias with optional override capability for existing aliases.
50
51
```python { .api }
52
def set_alias(self, name: str, desired_type: Type, override: bool = False) -> Container:
53
"""
54
Set a single alias mapping, optionally overriding existing aliases.
55
56
Args:
57
name: String name/alias for the service
58
desired_type: Type to associate with the name
59
override: If True, allows overriding existing aliases
60
61
Returns:
62
Container instance for method chaining
63
64
Raises:
65
AliasAlreadyDefined: If alias exists and override is False
66
"""
67
```
68
69
### Multiple Aliases Setting (Override)
70
71
Set multiple aliases with optional override capability.
72
73
```python { .api }
74
def set_aliases(self, values: AliasesTypeHint, override: bool = False) -> Container:
75
"""
76
Set multiple alias mappings, optionally overriding existing aliases.
77
78
Args:
79
values: Dictionary mapping names to types
80
override: If True, allows overriding existing aliases
81
82
Returns:
83
Container instance for method chaining
84
85
Raises:
86
AliasAlreadyDefined: If any alias exists and override is False
87
"""
88
```
89
90
## Types and Utilities
91
92
### Aliases Type Hint
93
94
Type definition for alias dictionaries mapping string names to types.
95
96
```python { .api }
97
AliasesTypeHint = Dict[str, Type]
98
```
99
100
### Standard Parameter Name Conversion
101
102
Utility function to convert class names to standard parameter names following Python conventions.
103
104
```python { .api }
105
def to_standard_param_name(name) -> str:
106
"""
107
Convert class names to standard parameter names.
108
109
Args:
110
name: Class name to convert
111
112
Returns:
113
Converted parameter name (e.g., "UserService" -> "user_service")
114
"""
115
```
116
117
## Usage Patterns
118
119
### Convention-based Registration
120
121
Register services using naming conventions instead of explicit type mappings:
122
123
```python
124
# Register services with conventional names
125
container.register(UserService)
126
container.register(DatabaseService)
127
container.register(EmailService)
128
129
# Add aliases for convention-based resolution
130
aliases = {
131
"user_service": UserService,
132
"database_service": DatabaseService,
133
"email_service": EmailService
134
}
135
container.add_aliases(aliases)
136
137
# Resolve by name
138
user_service = container.resolve("user_service")
139
```
140
141
### Parameter Name Resolution
142
143
Use aliases to enable parameter name-based dependency injection:
144
145
```python
146
def business_method(user_service, email_service, database_service):
147
# Method automatically gets services by parameter names
148
pass
149
150
# Services will be resolved by matching parameter names to aliases
151
services.exec(business_method)
152
```
153
154
### Configuration-driven Registration
155
156
Use aliases for configuration-driven service registration:
157
158
```python
159
# Configuration defines service mappings
160
service_config = {
161
"user_repository": "SqlUserRepository",
162
"email_provider": "SmtpEmailService",
163
"cache_provider": "RedisCache"
164
}
165
166
# Register services based on configuration
167
for alias, service_name in service_config.items():
168
service_type = globals()[service_name] # Get type by name
169
container.register(service_type)
170
container.add_alias(alias, service_type)
171
```
172
173
### Multi-environment Configuration
174
175
Use aliases to switch between different implementations:
176
177
```python
178
# Development environment
179
dev_aliases = {
180
"database": MockDatabase,
181
"email_service": ConsoleEmailService,
182
"storage": LocalFileStorage
183
}
184
185
# Production environment
186
prod_aliases = {
187
"database": PostgreSQLDatabase,
188
"email_service": SmtpEmailService,
189
"storage": S3Storage
190
}
191
192
# Register based on environment
193
if environment == "development":
194
container.set_aliases(dev_aliases, override=True)
195
else:
196
container.set_aliases(prod_aliases, override=True)
197
```
198
199
### Runtime Service Resolution
200
201
Resolve services dynamically at runtime using string names:
202
203
```python
204
def get_service_by_name(service_name: str):
205
"""Dynamically resolve service by name."""
206
return services.get(service_name)
207
208
# Usage
209
service_name = user_input # From user, config, etc.
210
service = get_service_by_name(service_name)
211
```
212
213
### Plugin Architecture
214
215
Use aliases to support plugin-based architectures:
216
217
```python
218
# Plugin registration
219
def register_plugin(plugin_name: str, plugin_class: Type):
220
container.register(plugin_class)
221
container.add_alias(f"plugin_{plugin_name}", plugin_class)
222
223
# Plugin loading
224
def load_plugin(plugin_name: str):
225
alias = f"plugin_{plugin_name}"
226
if alias in container:
227
return container.resolve(alias)
228
else:
229
raise ValueError(f"Plugin '{plugin_name}' not found")
230
```
231
232
## Exception Handling
233
234
Alias-related exceptions that may be raised during alias operations:
235
236
```python { .api }
237
class AliasAlreadyDefined(DIException):
238
"""Raised when attempting to add an alias that already exists."""
239
240
class AliasConfigurationError(DIException):
241
"""Raised when an alias references an unconfigured type."""
242
```
243
244
These exceptions help identify configuration issues:
245
246
```python
247
try:
248
container.add_alias("existing_alias", NewService)
249
except AliasAlreadyDefined:
250
# Handle duplicate alias
251
container.set_alias("existing_alias", NewService, override=True)
252
253
try:
254
service = container.resolve("unknown_alias")
255
except AliasConfigurationError:
256
# Handle missing alias configuration
257
logging.error("Service alias not configured")
258
```