or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

binding-specs.mddecorators.mderror-handling.mdfield-initialization.mdindex.mdobject-graph.mdscoping.md

binding-specs.mddocs/

0

# Binding Specifications

1

2

Custom binding configuration through BindingSpec classes that define explicit relationships between interfaces and implementations, enabling complex dependency scenarios beyond automatic resolution.

3

4

## Capabilities

5

6

### BindingSpec Base Class

7

8

Abstract base class for creating custom binding specifications that define how dependencies should be resolved.

9

10

```python { .api }

11

class BindingSpec(object):

12

def configure(self, bind):

13

"""

14

Configures bindings for the object graph.

15

16

Parameters:

17

- bind: binding configuration object for creating explicit bindings

18

19

Called by the object graph during initialization to register custom bindings.

20

"""

21

```

22

23

### Binding Configuration Methods

24

25

Methods available within BindingSpec.configure() for defining explicit bindings.

26

27

```python { .api }

28

class Binder(object):

29

def __call__(self, binding_key):

30

"""

31

Creates a binding for the specified key.

32

33

Parameters:

34

- binding_key: key to bind (typically a string matching parameter name)

35

36

Returns:

37

Binding configuration object with to_class(), to_instance(), and to_provider() methods

38

"""

39

40

def to_class(self, cls, in_scope=None):

41

"""

42

Binds to a specific class.

43

44

Parameters:

45

- cls: class to instantiate for this binding

46

- in_scope: scope ID for instances (SINGLETON, PROTOTYPE, or custom)

47

"""

48

49

def to_instance(self, instance):

50

"""

51

Binds to a specific instance.

52

53

Parameters:

54

- instance: pre-created instance to use for this binding

55

"""

56

57

def to_provider(self, provider_fn, in_scope=None):

58

"""

59

Binds to a provider function.

60

61

Parameters:

62

- provider_fn: function that returns instances for this binding

63

- in_scope: scope ID for instances

64

"""

65

```

66

67

## Usage Examples

68

69

### Basic Binding Specification

70

71

```python

72

import pinject

73

74

class DatabaseInterface(object):

75

pass

76

77

class PostgreSQLDatabase(DatabaseInterface):

78

def __init__(self):

79

self.connection = "postgresql://localhost"

80

81

class MySQLDatabase(DatabaseInterface):

82

def __init__(self):

83

self.connection = "mysql://localhost"

84

85

class DatabaseBindingSpec(pinject.BindingSpec):

86

def configure(self, bind):

87

# Bind interface to specific implementation

88

bind('database_interface').to_class(PostgreSQLDatabase)

89

90

class UserService(object):

91

def __init__(self, database_interface):

92

self.db = database_interface

93

94

obj_graph = pinject.new_object_graph(binding_specs=[DatabaseBindingSpec()])

95

user_service = obj_graph.provide(UserService)

96

print(user_service.db.connection) # "postgresql://localhost"

97

```

98

99

### Instance Bindings

100

101

```python

102

import pinject

103

104

class Configuration(object):

105

def __init__(self, env, debug):

106

self.environment = env

107

self.debug_mode = debug

108

109

class ConfigBindingSpec(pinject.BindingSpec):

110

def configure(self, bind):

111

# Bind to pre-created instances

112

prod_config = Configuration('production', False)

113

bind('configuration').to_instance(prod_config)

114

115

class AppService(object):

116

def __init__(self, configuration):

117

self.config = configuration

118

119

obj_graph = pinject.new_object_graph(binding_specs=[ConfigBindingSpec()])

120

app = obj_graph.provide(AppService)

121

print(app.config.environment) # "production"

122

```

123

124

### Provider Function Bindings

125

126

```python

127

import pinject

128

import logging

129

130

class LoggingBindingSpec(pinject.BindingSpec):

131

def configure(self, bind):

132

# Bind to provider functions

133

bind('logger').to_provider(self._create_logger, in_scope=pinject.SINGLETON)

134

bind('file_handler').to_provider(lambda: logging.FileHandler('app.log'))

135

136

def _create_logger(self, file_handler):

137

logger = logging.getLogger('myapp')

138

logger.addHandler(file_handler)

139

logger.setLevel(logging.INFO)

140

return logger

141

142

class AppService(object):

143

def __init__(self, logger):

144

self.logger = logger

145

146

obj_graph = pinject.new_object_graph(binding_specs=[LoggingBindingSpec()])

147

app = obj_graph.provide(AppService)

148

app.logger.info("Application started")

149

```

150

151

### Scoped Bindings

152

153

```python

154

import pinject

155

156

class DatabaseConnection(object):

157

def __init__(self):

158

self.connection_id = id(self)

159

160

class ConnectionBindingSpec(pinject.BindingSpec):

161

def configure(self, bind):

162

# Singleton: same instance shared across the application

163

bind('shared_connection').to_class(DatabaseConnection, in_scope=pinject.SINGLETON)

164

165

# Prototype: new instance every time

166

bind('temp_connection').to_class(DatabaseConnection, in_scope=pinject.PROTOTYPE)

167

168

class ServiceA(object):

169

def __init__(self, shared_connection, temp_connection):

170

self.shared = shared_connection

171

self.temp = temp_connection

172

173

class ServiceB(object):

174

def __init__(self, shared_connection, temp_connection):

175

self.shared = shared_connection

176

self.temp = temp_connection

177

178

obj_graph = pinject.new_object_graph(binding_specs=[ConnectionBindingSpec()])

179

service_a = obj_graph.provide(ServiceA)

180

service_b = obj_graph.provide(ServiceB)

181

182

# Shared connections are the same instance

183

print(service_a.shared.connection_id == service_b.shared.connection_id) # True

184

185

# Temp connections are different instances

186

print(service_a.temp.connection_id == service_b.temp.connection_id) # False

187

```

188

189

### Provider Methods with Dependencies

190

191

```python

192

import pinject

193

194

class DatabaseConfig(object):

195

def __init__(self):

196

self.host = "localhost"

197

self.port = 5432

198

199

class DatabaseConnection(object):

200

def __init__(self, host, port):

201

self.host = host

202

self.port = port

203

204

class DatabaseBindingSpec(pinject.BindingSpec):

205

def configure(self, bind):

206

bind('database_config').to_class(DatabaseConfig)

207

bind('database_connection').to_provider(self._create_connection)

208

209

def _create_connection(self, database_config):

210

# Provider methods can have their own dependencies injected

211

return DatabaseConnection(database_config.host, database_config.port)

212

213

obj_graph = pinject.new_object_graph(binding_specs=[DatabaseBindingSpec()])

214

connection = obj_graph.provide(DatabaseConnection)

215

```