Skip to content

Commit b10e2cf

Browse files
feat: document resource management
Signed-off-by: SalathielGenese <salathielgenese@gmail.com>
1 parent 704a32e commit b10e2cf

1 file changed

Lines changed: 55 additions & 2 deletions

File tree

README.md

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ rely on reflect-metadata for true IoC.
2626
registrations, missing dependencies, and more
2727
+ [x] **No External Dependencies**
2828
+ [ ] `Token` default values
29-
+ [ ] Containers as resources and and resources with disposal hooks
30-
+ [ ] Containers as parameters to `resolver` and `generator` definitions
29+
+ [x] Containers as resources, and dependencies with disposal hooks
30+
+ [x] Context as parameters to `resolver` and `generator` defintion functions
3131
+ [ ] Support a `Configuration` abstraction for defining, importing & excluding
3232
some sets of dependency definitions (think a full set of configuration for
3333
Redis, Datadog, logging, etc)
@@ -196,6 +196,8 @@ console.log(child.get( Date ) === root.get(Date)); // true
196196
```
197197

198198
### Forward References:
199+
200+
When a token is defined later than its usage, leverage forward reference:
199201
```ts
200202
import { Container, Inject } from "@sansar/dependency";
201203

@@ -211,6 +213,57 @@ console.log(new Container().get( A ) instanceof A); // true
211213
console.log(new Container().get( A ).b instanceof B); // true
212214
```
213215

216+
### Resources Management
217+
218+
The `Container` class is EcmaScript-compliant by implementing the
219+
`[Symbol.dispose]` method. Futhermore, any dependency object, whether a static
220+
value, injected, resolver- or generator-based, that implements the
221+
`[Symbol.dispose]` method will be invoked when the container resource is cleaned
222+
up.
223+
224+
I case you do control the dependent value implementation, you can:
225+
+ pass an `onDestroy` callback to the dependency provider when registering it
226+
+ call `onDestroy( hook )` with your disposal hook yourself from the `Context`
227+
object passed to `resolver`s and `generator`s.
228+
229+
> **NOTE:** A dependency lifecycle is tied to its related container lifetime.
230+
> This is relevant for scoped dependencies which are tied to the contained with
231+
> the matching scope.
232+
233+
> **NOTE:** When a container is disposed, it propagates to descendant
234+
> containers. We hope this helps preventing some weird inconsistencies.
235+
236+
```ts
237+
import { Container, Inject, Token } from "@sansar/dependency";
238+
239+
class A extends Token<number> {}
240+
241+
class B {}
242+
243+
@Inject(A, B)
244+
class C {
245+
[Symbol.dispose]() {/* 1 */}
246+
}
247+
248+
const scope = Symbol();
249+
const root = new Container()
250+
.register(A, { value: Math.PI, onDestroy() {/* 2 */} })
251+
.register(B, {
252+
scope,
253+
resolver: ctx => {
254+
ctx.onDestroy(bValue => {/* 3 */})
255+
return Math.random();
256+
}});
257+
const container = new Container({ scope, parent: root });
258+
259+
container.get( C );
260+
(() => { using _ = container; });
261+
// when container goes out of scope, its [Symbol.dispose] is called
262+
// so it the B instance cached there, through the #3 onDestroy hook
263+
264+
// when root goes out of scope or is disposed of, so will A (#2) and C (#1).
265+
```
266+
214267

215268

216269
## Contributing

0 commit comments

Comments
 (0)