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

factory-registration.mddocs/

0

# Factory Registration

1

2

Advanced service registration using factory functions for complex instantiation scenarios. Supports different factory signatures, service lifestyles, and provides flexibility for services that require custom initialization logic.

3

4

## Capabilities

5

6

### Singleton Factory Registration

7

8

Registers a factory function that creates singleton services - the factory is called once and the result is cached.

9

10

```python { .api }

11

def add_singleton_by_factory(self, factory: FactoryCallableType, return_type: Optional[Type] = None) -> Container:

12

"""

13

Register a singleton service created by a factory function.

14

15

Args:

16

factory: Factory function to create the service instance

17

return_type: Expected return type (inferred from factory if not provided)

18

19

Returns:

20

Container instance for method chaining

21

"""

22

```

23

24

### Transient Factory Registration

25

26

Registers a factory function that creates transient services - the factory is called every time the service is resolved.

27

28

```python { .api }

29

def add_transient_by_factory(self, factory: FactoryCallableType, return_type: Optional[Type] = None) -> Container:

30

"""

31

Register a transient service created by a factory function.

32

33

Args:

34

factory: Factory function to create service instances

35

return_type: Expected return type (inferred from factory if not provided)

36

37

Returns:

38

Container instance for method chaining

39

"""

40

```

41

42

### Scoped Factory Registration

43

44

Registers a factory function that creates scoped services - the factory is called once per scope and the result is cached within that scope.

45

46

```python { .api }

47

def add_scoped_by_factory(self, factory: FactoryCallableType, return_type: Optional[Type] = None) -> Container:

48

"""

49

Register a scoped service created by a factory function.

50

51

Args:

52

factory: Factory function to create service instances

53

return_type: Expected return type (inferred from factory if not provided)

54

55

Returns:

56

Container instance for method chaining

57

"""

58

```

59

60

## Factory Function Types

61

62

Rodi supports three different factory function signatures for maximum flexibility:

63

64

### No Arguments Factory

65

66

Simple factory functions that take no arguments and create service instances.

67

68

```python { .api }

69

FactoryCallableNoArguments = Callable[[], Any]

70

```

71

72

Usage example:

73

74

```python

75

def create_database_service():

76

connection_string = get_connection_string_from_config()

77

return DatabaseService(connection_string)

78

79

container.add_singleton_by_factory(create_database_service, DatabaseService)

80

```

81

82

### Single Argument Factory (Scope)

83

84

Factory functions that take an ActivationScope parameter for context-aware service creation.

85

86

```python { .api }

87

FactoryCallableSingleArgument = Callable[[ActivationScope], Any]

88

```

89

90

Usage example:

91

92

```python

93

def create_request_logger(scope: ActivationScope):

94

request_context = scope.get(RequestContext)

95

return Logger(f"Request-{request_context.request_id}")

96

97

container.add_scoped_by_factory(create_request_logger, Logger)

98

```

99

100

### Two Arguments Factory (Scope and Type)

101

102

Factory functions that take both an ActivationScope and the requested Type for advanced factory scenarios.

103

104

```python { .api }

105

FactoryCallableTwoArguments = Callable[[ActivationScope, Type], Any]

106

```

107

108

Usage example:

109

110

```python

111

def create_generic_repository(scope: ActivationScope, entity_type: Type):

112

db_context = scope.get(DatabaseContext)

113

return GenericRepository(db_context, entity_type)

114

115

container.add_scoped_by_factory(create_generic_repository)

116

```

117

118

### Factory Type Union

119

120

Combined type hint for all supported factory function signatures.

121

122

```python { .api }

123

FactoryCallableType = Union[FactoryCallableNoArguments, FactoryCallableSingleArgument, FactoryCallableTwoArguments]

124

```

125

126

## Factory Registration Patterns

127

128

### Configuration-based Services

129

130

Use factories to create services that depend on external configuration:

131

132

```python

133

def create_email_service():

134

config = load_email_config()

135

if config.provider == "smtp":

136

return SmtpEmailService(config.smtp_settings)

137

elif config.provider == "sendgrid":

138

return SendGridEmailService(config.api_key)

139

else:

140

raise ValueError(f"Unknown email provider: {config.provider}")

141

142

container.add_singleton_by_factory(create_email_service, EmailService)

143

```

144

145

### Environment-specific Services

146

147

Create different service implementations based on environment:

148

149

```python

150

def create_storage_service():

151

if os.getenv("ENVIRONMENT") == "production":

152

return S3StorageService(

153

bucket=os.getenv("S3_BUCKET"),

154

access_key=os.getenv("AWS_ACCESS_KEY")

155

)

156

else:

157

return LocalFileStorageService(path="./storage")

158

159

container.add_singleton_by_factory(create_storage_service, StorageService)

160

```

161

162

### Complex Initialization

163

164

Use factories for services requiring complex initialization logic:

165

166

```python

167

def create_cache_service(scope: ActivationScope):

168

config = scope.get(CacheConfiguration)

169

170

# Complex setup logic

171

cache = RedisCache(config.connection_string)

172

cache.set_serializer(JsonSerializer())

173

cache.configure_eviction_policy(config.eviction_policy)

174

175

# Setup cache warming

176

if config.warm_cache:

177

cache.warm_up(config.warm_up_keys)

178

179

return cache

180

181

container.add_singleton_by_factory(create_cache_service, CacheService)

182

```

183

184

### Conditional Service Creation

185

186

Create services conditionally based on runtime state:

187

188

```python

189

def create_audit_service(scope: ActivationScope):

190

user = scope.get(CurrentUser)

191

192

if user.requires_audit_logging:

193

return DatabaseAuditService(scope.get(AuditDatabase))

194

else:

195

return NoOpAuditService()

196

197

container.add_scoped_by_factory(create_audit_service, AuditService)

198

```

199

200