Dependency Injection
Disposing Services
Cleaning up services with app.dispose and provider.dispose, closing the navigation scope, tracking transient instances.
Disposing services
The provider disposes the instances it built itself. If a service holds a resource such as a timer, a listener or a connection, write a dispose() method that releases it; calling it is the provider's job:
@Injectable({ lifetime: "singleton" })
export class SyncService {
private timer = setInterval(() => this.pull(), 60_000);
async pull() {
const response = await fetch("/api/notes");
return response.json();
}
dispose() {
clearInterval(this.timer);
}
}
@Injectable({ lifetime: "singleton" })
export class SyncService {
timer = setInterval(() => this.pull(), 60_000);
async pull() {
const response = await fetch("/api/notes");
return response.json();
}
dispose() {
clearInterval(this.timer);
}
}
When they are disposed:
app.dispose()disposes the services after the component tree has been torn down (leave animations included); until then, every component'sonDisposing/onDisposedsees the same services, andawait app.dispose()also waits for asyncdisposes.app.dispose()andprovider.dispose()dispose the instances the provider built: the singleton cache, thescopedinstances of scopes, and the navigation scopes.- A navigation scope closes when a new navigation takes its place or when the navigation is cancelled, and its
scopedinstances are disposed. If a page tied to the scope is still alive (a leaving page whose disposal is in progress, a page in thekeepAlivecache or kept in the stack), the scope stays open until that page is disposed or shown again.
How: on every instance, dispose(), close(), [Symbol.dispose]() and [Symbol.asyncDispose]() are called in order if they exist; an error thrown by one does not stop the others.
Only instances that have been built are disposed: a singleton that was never asked for was never built, so it is not disposed either; a value given with useValue goes through this only if it has been resolved at least once.
transient instances are not tracked by default; when provider.enableAutoDisposeTransients() is turned on, transient instances produced in a child scope (createScope, a navigation scope) are disposed together with that scope. Transients resolved from the root provider are still not tracked.
provider.getAllServices() gives the ServiceCollection the provider uses.
Next step
For the mechanisms that writing packages on MotifJS relies on, go on to Writing Packages on Motif.