The container creates your services, so it also cleans them up. Two optional hooks run at the edges of an instance’s
life: onInit after it is constructed, and onDestroy (or a standard dispose method) when its owner is disposed.
class
classDatabase
Databaseimplements
(alias) interfaceLifecycleHooks
importLifecycleHooks
Optional lifecycle hooks. onInit runs after construction (class registrations);
onDestroy runs when the owning provider or scope is disposed.
[Symbol.asyncDispose] and [Symbol.dispose] are honored too.
LifecycleHooks {
private
Database.pool?: {
end():Promise<void>;
} |undefined
pool?: {
functionend():Promise<void>
end():
interfacePromise<T>
Represents the completion of an asynchronous operation
Promise<void> };
async
Database.onInit(): Promise<void>
onInit() {
this.
Database.pool?: {
end():Promise<void>;
} |undefined
pool=await
functionconnect(url:string):Promise<{
end():Promise<void>;
}>
connect('postgres://localhost/app'); // awaited before anyone receives the instance
Resolves token, throwing ServiceNotFoundError if it is not registered.
getRequiredService(
classDatabase
Database); // connected
await
constprovider:ServiceProvider
provider.
ServiceProvider.dispose(): Promise<void>
Disposes every instance this provider (or scope) created, in reverse creation order:
onDestroy(), else [Symbol.asyncDispose](), else [Symbol.dispose](). Disposing the root
disposes singletons; disposing a scope disposes its scoped and transient instances.
Every instance is disposed even if some throw; the errors are rethrown afterwards
(an AggregateError if more than one). Later calls wait for the first one and do not rethrow.
dispose(); // pool closed
LifecycleHooks is an optional interface for autocompletion. The container only checks whether the methods exist.
Runs right after the constructor, and is awaited if it returns a promise. The caller of getRequiredService, and any
service that depends on this one, gets the instance only after onInit has finished.
Runs once per instance: once for a singleton, once per scope for a scoped service, every time for a transient.
Runs for class registrations only. A factory already controls construction, so it does its own
async setup before returning; onInit on a factory’s result is not called. Values are never initialised either.
If it throws, the resolution rejects with that error and nothing is cached, so the next resolution builds a new
instance. The failed instance was already constructed, so it is still disposed with its owner: onDestroy must
cope with a half-initialised object.
Use it for async setup a constructor can’t do: opening a connection, warming a cache, reading a file.
await provider.dispose() (or await scope.dispose(), or leaving an await using block) disposes every instance
that provider created and still tracks. For each instance it calls the first of these that exists:
onDestroy()
[Symbol.asyncDispose]()
[Symbol.dispose]()
So classes written for the standard explicit resource management
protocol work without changes, and a class that has both an onDestroy and a Symbol.dispose is disposed only once.
A method that is used to asynchronously release resources held by an object. Called by the semantics of the await using statement.
asyncDispose]() {
var console:Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
If a provider or scope is disposed while one of its services is still being built (an async factory or onInit is
still running), that service is disposed as soon as construction finishes, and the pending get* call rejects with
DisposedError. A shutdown in the middle of a request doesn’t leak a connection that was being opened.
Instances are disposed one at a time, awaiting each, in reverse creation order. A service is created after its
dependencies, so it is disposed before them: a repository closes before the pool it uses, the pool before the logger.
const
constlog:string[]
log:string[] = [];
class
classLogger
Logger {
Logger.onDestroy(): void
onDestroy() {
constlog:string[]
log.
Array<string>.push(...items: string[]): number
Appends new elements to the end of an array, and returns the new length of the array.
@param ― items New elements to add to the array.
push('Logger');
}
}
class
classPool
Pool {
constructor(readonly
Pool.logger: Logger
logger:
classLogger
Logger) {}
Pool.onDestroy(): void
onDestroy() {
constlog:string[]
log.
Array<string>.push(...items: string[]): number
Appends new elements to the end of an array, and returns the new length of the array.
@param ― items New elements to add to the array.
push('Pool');
}
}
class
classRepo
Repo {
constructor(readonly
Repo.pool: Pool
pool:
classPool
Pool) {}
Repo.onDestroy(): void
onDestroy() {
constlog:string[]
log.
Array<string>.push(...items: string[]): number
Appends new elements to the end of an array, and returns the new length of the array.
Resolves token, throwing ServiceNotFoundError if it is not registered.
getRequiredService(
classRepo
Repo);
await
constprovider:ServiceProvider
provider.
ServiceProvider.dispose(): Promise<void>
Disposes every instance this provider (or scope) created, in reverse creation order:
onDestroy(), else [Symbol.asyncDispose](), else [Symbol.dispose](). Disposing the root
disposes singletons; disposing a scope disposes its scoped and transient instances.
Every instance is disposed even if some throw; the errors are rethrown afterwards
(an AggregateError if more than one). Later calls wait for the first one and do not rethrow.
dispose();
var console:Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
Every instance is disposed even if some of them throw. After the last one, the error is rethrown: the error itself if
one instance failed, or an AggregateError with all of them if several did.
try {
await
constprovider:ServiceProvider
provider.
ServiceProvider.dispose(): Promise<void>
Disposes every instance this provider (or scope) created, in reverse creation order:
onDestroy(), else [Symbol.asyncDispose](), else [Symbol.dispose](). Disposing the root
disposes singletons; disposing a scope disposes its scoped and transient instances.
Every instance is disposed even if some throw; the errors are rethrown afterwards
(an AggregateError if more than one). Later calls wait for the first one and do not rethrow.
dispose();
} catch (
var error:unknown
error) {
const
consterrors:any[]
errors=
var error:unknown
errorinstanceof
var AggregateError:AggregateErrorConstructor
AggregateError?
var error:AggregateError
error.
AggregateError.errors: any[]
errors: [
var error:unknown
error];
for (const
conste:any
eof
consterrors:any[]
errors)
var console:Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stderr with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
constcode=5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
If formatting elements (e.g. %d) are not found in the first string then
util.inspect() is called on each argument and the
resulting string values are concatenated. See util.format()
for more information.
@since ― v0.1.100
error('dispose failed:',
conste:any
e);
}
The provider counts as disposed either way: further resolutions throw DisposedError. Calling dispose() again, or
concurrently (two shutdown hooks, await using plus an explicit call), waits for the first disposal to finish and
resolves without rethrowing its errors: only the first caller sees them.