or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aliases-names.mdcontainer-configuration.mdfactory-registration.mdindex.mdscoped-services.mdservice-resolution.md

aliases-names.mddocs/

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

```