The Injector is the heart of DI. The package exports a default injector as injector, and you can create additional injector instances with new Injector().
import { Injector, injector } from "@kayahr/di";
const defaultInjector = injector;
const customInjector = new Injector();
Dependencies can be registered with setClass, setFactory, setValue, and setFunction:
const loggerToken = new InjectionToken<Logger>("console-logger");
const numberToken = new InjectionToken<number>("just-a-number");
injector.setClass(UserService);
injector.setClass(ConsoleLogger, { provide: Logger, token: loggerToken });
injector.setFactory(UserDAO, UserDAO.create, { inject: [ DBService ] });
injector.setValue(123, numberToken);
injector.setFunction(closeDatabase, [ Database ]);
Classes and static factory methods can also be registered with the injectable decorator. Functions, plain factory functions, and values can not.
Use provide when a class should also be resolvable through one of its base classes.
At least once in an application you have to resolve a root dependency manually. Choose between get, getSync, and getAsync:
get returns a synchronous value when possible, otherwise a promise.getAsync always returns a promise.getSync always returns a synchronous value and throws when an asynchronous dependency is involved.const userService = injector.getSync(UserService);
const userDAO = await injector.getAsync(UserDAO);
let dbService = injector.get(DBService);
if (dbService instanceof Promise) {
dbService = await dbService;
}
Use has if you only want to check availability:
if (injector.has(DBService)) {
// ...
}
remove removes the whole local provider registration matching the qualifier.
That means any qualifier alias of the same local registration is sufficient:
remove(Component) also removes registrations by token or qualified type.remove(componentToken) also removes the class registration.const componentToken = new InjectionToken<Component>("foo");
injector.setClass(Component, { token: componentToken });
injector.remove(Component); // removes Component and componentToken
// injector.remove(componentToken); // same effect
After the call above, none of these qualifiers resolve anymore:
injector.has(Component); // false
injector.has(componentToken); // false
remove only affects the specified scope (root scope by default). Parent-scope registrations are not touched.
remove(...) disposes a cached synchronous singleton before returning. If the cached singleton implements AsyncDisposable, it throws an InjectionError without removing the registration. Use await removeAsync(...) to remove it and await its asynchronous disposal. removeAsync(...) also supports synchronous disposables.
All injector methods accept an additional scope option. By default all these methods use the root scope. See Scopes documentation for details.