You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+69-2Lines changed: 69 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,6 +41,8 @@ These capabilities are implemented by components of the application, with some c
41
41
42
42
## Usage
43
43
44
+
### Creating a container module and defining services
45
+
44
46
Take the example of a logging component, that defines services in a container using the following keys (see [./examples/container/loggingModule/keys.ts](https://github.com/mgdigital/tsinject/blob/main/examples/container/loggingModule/keys.ts)):
Note that we should only call [IContainer.get](https://mgdigital.github.io/tsinject/interfaces/IContainer.html#get) from within a factory function or from the [composition root](https://freecontent.manning.com/dependency-injection-in-net-2nd-edition-understanding-the-composition-root/), avoiding the [service locator anti-pattern](https://freecontent.manning.com/the-service-locator-anti-pattern/).
143
+
**Note:** We should only call [IContainer.get](https://mgdigital.github.io/tsinject/interfaces/IContainer.html#get) from within a factory function or from the [composition root](https://freecontent.manning.com/dependency-injection-in-net-2nd-edition-understanding-the-composition-root/), avoiding the [service locator anti-pattern](https://freecontent.manning.com/the-service-locator-anti-pattern/).
144
+
145
+
**Note:** When defining a service in the container, if that service key is already defined then the key will **not** be overwritten. This allows modules to be used multiple times without introducing unpredictable behaviour when using decorators. For example of module A and B both depend on module C they can both use module C and then be used together in the same container. If an already defined service needs to be overwritten, this can be done with a decorator.
146
+
147
+
## Decorators
148
+
149
+
Decorators allow us to modify an already-defined service. Let's create a custom logging module that decorates some of the services in the base module defined above:
// Decorate the logger config so that output is always pretty
161
+
.decorate(
162
+
loggingModule.keys.loggerConfig,
163
+
factory=>container=> ({
164
+
...factory(container),
165
+
pretty: true
166
+
})
167
+
)
168
+
// Overwrite the log writer with some other implementation
169
+
.decorate(
170
+
loggingModule.keys.logWriter,
171
+
() => () =>myCustomLogWriter
172
+
)
173
+
```
174
+
175
+
We can also use decorators to achieve features that aren't explicitly implemented in this library, such as service tagging, which we can do by defining a service as an array:
// Add a service to the array of already defined services
203
+
factory=>container=> [
204
+
...factory(container),
205
+
{ foo: 'bar' }
206
+
]
207
+
)
208
+
```
142
209
143
210
And that's it - unlike some other DI containers that claim to be lightweight, tsinject really is tiny and has a simple API, allowing large and complex but loosely coupled applications to be built from small, simple and easily testable components.
144
211
145
212
See the [examples](https://github.com/mgdigital/tsinject/tree/main/examples) folder for a more complete application. It includes a simple tasks service with a REST API that can be started by cloning this repository and running `yarn install`, `yarn build` then `yarn example:start`.
146
213
147
214
---
148
215
149
-
Copyright (c) 2021 Mike Gibson, https://github.com/mgdigital.
216
+
Copyright (c) 2021 Mike Gibson, https://github.com/mgdigital
0 commit comments