Skip to content

Instantly share code, notes, and snippets.

@vahidvdn
Created March 6, 2024 10:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vahidvdn/f80a00fdb90de727dc3270553226f16c to your computer and use it in GitHub Desktop.
Save vahidvdn/f80a00fdb90de727dc3270553226f16c to your computer and use it in GitHub Desktop.
DI container
export interface Type<T = any> {
new (...args: any[]): T;
}
class Container {
public dependencies = [];
public init(deps: any[]) {
deps.map((target) => {
const isInjectable = Reflect.getMetadata('injectable', target);
if (!isInjectable) return;
const paramTypes = Reflect.getMetadata('design:paramtypes', target) || [];
// resolve dependecies of current dependency
const childrenDep = paramTypes.map((paramType) => {
// recursively resolve all child dependencies:
this.init([paramType]);
if (!this.dependencies[paramType.name]) {
this.dependencies[paramType.name] = new paramType();
return this.dependencies[paramType.name];
}
return this.dependencies[paramType.name];
});
// resolve dependency by injection child classes that already resolved
if (!this.dependencies[target.name]) {
this.dependencies[target.name] = new target(...childrenDep);
}
});
return this;
}
public get<T extends new (...args: any[]) => any>(
serviceClass: T,
): InstanceType<T> {
return this.dependencies[serviceClass.name];
}
}
function Injectable() {
return function (target: any) {
Reflect.defineMetadata('injectable', true, target);
};
}
// main
@Injectable()
class ProductService {
constructor() {}
getProducts() {
console.log('getting products..!! 🍊🍊🍊');
}
}
@Injectable()
class OrderService {
constructor(private productService: ProductService) {}
getOrders() {
console.log('getting orders..!! 📦📦📦');
this.productService.getProducts();
}
}
@Injectable()
class UserService {
constructor(private orderService: OrderService) {}
getUsers() {
console.log('getUsers runs!');
this.orderService.getOrders();
}
}
// export const app = new Container().init([OrderService, UserService]);
export const app = new Container().init([UserService]);
const userService = app.get(UserService);
userService.getUsers();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment