DI Hierarchy
InversifyJS is a popular library for implementing inversion of control (IoC) and dependency injection (DI) in TypeScript applications. It supports hierarchical dependency injection, which can be a powerful tool in complex applications.
With InversifyJS's hierarchical injection system, you can create a hierarchy of containers where each container can have a parent container. This allows for better organization and separation of concerns in your application.
When a dependency needs to be injected, InversifyJS starts by looking in the current container for a binding. If the binding is not found, it moves up the hierarchy to the parent container and continues the search. This process continues until a binding is found or the top-level parent container is reached.
Found bindings might override ancestor bindings even if their constraints are not met. For example, if a named binding is found in the child container for the requested service, that binding overrides parent bindings even if this binding is later discarded in a non-named resolution request.
When using hierarchical injection, be aware that cached bindings from the first resolution will be used for subsequent resolution, even if the call comes from another child container.
@injectable()
class Samurai {
constructor(
@inject(Katana)
public katana: Katana,
) {}
}
const parentContainer: Container = new Container();
parentContainer.bind(Samurai).toSelf().inSingletonScope();
parentContainer.bind(Katana).toSelf();
const childContainer: Container = parentContainer.createChild();
childContainer.bind(Katana).to(LegendaryKatana);
// The result of this resolution will be cached in the samurai binding
childContainer.get(Samurai);
// This samurai will have a LegendaryKatana injected
const samurai: Samurai = parentContainer.get(Samurai);
If this behaviour is unwanted, consider using ContainerModule
instead. This way, you can load it in both containers. Different containers will have different binding and therefore different cached values.
By using InversifyJS's hierarchical injection system, you can easily manage complex dependencies and keep your code clean and modular. It provides a flexible and scalable solution for handling dependencies in your TypeScript applications.
class Katana {}
const parentContainer: Container = new Container();
parentContainer.bind(weaponIdentifier).to(Katana);
const childContainer: Container = parentContainer.createChild();
const katana: Katana = childContainer.get(weaponIdentifier);