@@ -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
200202import { Container , Inject } from " @sansar/dependency" ;
201203
@@ -211,6 +213,57 @@ console.log(new Container().get( A ) instanceof A); // true
211213console .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