or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

amount-utilities.mdcontainer-di.mddata-utilities.mderror-handling.mdindex.mdserver-utilities.mdutility-functions.md

container-di.mddocs/

0

# Container & Dependency Injection

1

2

Enhanced Awilix dependency injection container with additional registration patterns optimized for Medusa's service architecture, including array-based registration and scoped container creation.

3

4

## Capabilities

5

6

### MedusaContainer Type

7

8

Extended Awilix container type with additional methods for enhanced dependency injection patterns.

9

10

```typescript { .api }

11

import { AwilixContainer } from "awilix";

12

13

type MedusaContainer = AwilixContainer & {

14

/** Register multiple services under the same name as an array */

15

registerAdd: <T>(name: string, registration: T) => MedusaContainer;

16

/** Create a scoped container with inherited registerAdd functionality */

17

createScope: () => MedusaContainer;

18

};

19

```

20

21

### Container Creation

22

23

Creates an enhanced Medusa container with additional registration capabilities.

24

25

```typescript { .api }

26

/**

27

* Creates an enhanced Awilix container with additional registration methods

28

* @param args - Arguments passed to Awilix createContainer function

29

* @returns Enhanced container with registerAdd and enhanced createScope methods

30

*/

31

function createMedusaContainer(...args): MedusaContainer;

32

```

33

34

**Usage Examples:**

35

36

```typescript

37

import { createMedusaContainer } from "medusa-core-utils";

38

import { asClass, asFunction, asValue } from "awilix";

39

40

// Create a new container

41

const container = createMedusaContainer();

42

43

// Standard Awilix registration

44

container.register({

45

userService: asClass(UserService).singleton(),

46

database: asValue(databaseConnection),

47

logger: asFunction(() => new Logger()).singleton()

48

});

49

50

// Enhanced array-based registration with registerAdd

51

container.registerAdd("eventHandlers", asClass(UserCreatedHandler));

52

container.registerAdd("eventHandlers", asClass(UserUpdatedHandler));

53

container.registerAdd("eventHandlers", asClass(UserDeletedHandler));

54

55

// Resolve all event handlers as an array

56

const handlers = container.resolve("eventHandlers");

57

// handlers is an array containing instances of all registered handlers

58

59

// Create scoped containers

60

const requestScope = container.createScope();

61

requestScope.register({

62

requestId: asValue(generateRequestId()),

63

currentUser: asValue(user)

64

});

65

```

66

67

### Array Registration (registerAdd)

68

69

Register multiple services under the same name, creating an array of resolved services.

70

71

```typescript { .api }

72

/**

73

* Register a service to be added to an array of services under the given name

74

* @param name - The name to register the service under

75

* @param registration - The Awilix registration (asClass, asFunction, asValue)

76

* @returns The container instance for chaining

77

*/

78

registerAdd<T>(name: string, registration: T): MedusaContainer;

79

```

80

81

**Usage Examples:**

82

83

```typescript

84

import { createMedusaContainer } from "medusa-core-utils";

85

import { asClass, asFunction } from "awilix";

86

87

const container = createMedusaContainer();

88

89

// Register multiple middleware functions

90

container.registerAdd("middleware", asFunction(() => authMiddleware));

91

container.registerAdd("middleware", asFunction(() => loggingMiddleware));

92

container.registerAdd("middleware", asFunction(() => errorHandlingMiddleware));

93

94

// Register multiple validators

95

container.registerAdd("validators", asClass(EmailValidator));

96

container.registerAdd("validators", asClass(PhoneValidator));

97

container.registerAdd("validators", asClass(AddressValidator));

98

99

// Resolve all registered items as arrays

100

const middlewareList = container.resolve("middleware");

101

const validatorList = container.resolve("validators");

102

103

// Use in application

104

middlewareList.forEach(middleware => app.use(middleware));

105

validatorList.forEach(validator => registerValidator(validator));

106

```

107

108

### Scoped Containers

109

110

Create isolated container scopes that inherit from the parent container while maintaining enhanced functionality.

111

112

```typescript { .api }

113

/**

114

* Create a scoped container that inherits registrations from parent

115

* @returns New scoped container with registerAdd functionality

116

*/

117

createScope(): MedusaContainer;

118

```

119

120

**Usage Examples:**

121

122

```typescript

123

import { createMedusaContainer } from "medusa-core-utils";

124

import { asValue, asClass } from "awilix";

125

126

const container = createMedusaContainer();

127

128

// Register global services

129

container.register({

130

database: asValue(databaseConnection),

131

logger: asClass(Logger).singleton()

132

});

133

134

// Create request-scoped container

135

app.use((req, res, next) => {

136

const requestScope = container.createScope();

137

138

// Add request-specific registrations

139

requestScope.register({

140

requestId: asValue(req.id),

141

currentUser: asValue(req.user),

142

requestLogger: asValue(logger.child({ requestId: req.id }))

143

});

144

145

// Request scope can still use registerAdd

146

requestScope.registerAdd("requestHandlers", asClass(AuthHandler));

147

requestScope.registerAdd("requestHandlers", asClass(ValidationHandler));

148

149

req.container = requestScope;

150

next();

151

});

152

153

// In route handlers

154

app.get("/users", (req, res) => {

155

const userService = req.container.resolve("userService");

156

const handlers = req.container.resolve("requestHandlers");

157

158

// Process request with scoped dependencies

159

});

160

```