npm i microdi2
First, let's imagine we have such classes, one depends on another one.
// IA.ts
export interface A {
a(): string;
}
// A.ts
import type { IA } from "./IA";
export class A implements IA {
public a(): string {
return "A";
}
}
// IB.ts
export interface IB {
b(): string;
}
// B.ts
import type { IA } from "./IA";
import type { IB } from "./IB";
export class B implements IB {
public constructor(private readonly a: IA) {}
public b() {
return "B";
}
}
All of them must be instantiated, so we'll apply this logic to do that:
export const instanceB = new B(new A());
Looks simple, right? But when a class has a lot of dependencies and Its dependencies has their own dependencies (and so on), the instantiation logic might be very complicated:
const app = new App(new Router(), new Authorization(new HttpClient(new UserService)), new Whatever(), ...);
Simple? Not quite.
We may have a container that resolves our dependencies (and event instantiate classes on demand):
// container.ts
// Container has been initialized internally:
import { initContainer } from "microdi2";
export const { provide, singleton, alwaysFresh } = initContainer();
// DIConfig.ts:
import { singleton } from "./container.ts";
import { A } from "./A";
import type { IA } from "./IA";
import { B } from "./B";
import type { IB } from "./IB";
export const resolveA = singleton<IA>(
// Identifier
"IA",
// Class
A,
// Dependency list
[]
);
export const resolveB = singleton<IB>(
// Identifier
"IB",
// Class
B,
// B constructor must be invoked with an instance of IA type
["IA"]
);
And then, all of these classes can be received with the following:
// app.ts
import { resolve } from "./container.ts";
import { IB } from "./IB";
import { resolveB } from "./DIConfig.ts";
// approach 1 (define type manually)
const instanceB1 = resolve<IB>("IB");
// approach 2 (use exported resolver):
const instanceB1 = resolveB();
console.log(instanceB1 === instanceB2); // true
Please note the example above instantiates all the classes as singletons. If you need a class to be instantiated every time you
resolve
them, usealwaysFresh
instead