[added] - inversify for inversion of control (IoC) container
This commit is contained in:
@@ -43,7 +43,7 @@ class App {
|
||||
}
|
||||
|
||||
public listen(port: number): ReturnType<typeof this.app.listen> {
|
||||
return this.app.listen(port, () => {
|
||||
return this.app.listen(port, () => {
|
||||
logger.info(`Server listening on port ${config.port}`);
|
||||
logger.info(`Environment :- ${config.env}`);
|
||||
})
|
||||
|
||||
@@ -2,11 +2,15 @@ import { Request, Response } from 'express';
|
||||
import { IProductInteractor } from '../interfaces/IProductInteractor';
|
||||
import ApiResponse from '../utils/helper/ApiResponse';
|
||||
import { AsyncHandler } from '../utils/handler/async.handler';
|
||||
|
||||
import { inject, injectable } from 'inversify';
|
||||
import { INTERFACE_TYPE } from '../utils';
|
||||
@injectable()
|
||||
export class ProductController {
|
||||
private interactor: IProductInteractor;
|
||||
|
||||
constructor(interactor: IProductInteractor) {
|
||||
constructor(
|
||||
@inject(INTERFACE_TYPE.ProductInteractor) interactor: IProductInteractor
|
||||
) {
|
||||
this.interactor = interactor;
|
||||
}
|
||||
|
||||
|
||||
11
src/external-libraries/mailer.ts
Normal file
11
src/external-libraries/mailer.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { injectable } from "inversify";
|
||||
import logger from "../config/logger";
|
||||
import { IMailer } from "../interfaces/IMailer";
|
||||
|
||||
@injectable()
|
||||
export class Mailer implements IMailer {
|
||||
async SendMail(to: string, subject: string, body: unknown): Promise<boolean> {
|
||||
logger.debug("Sending mail...", { to, subject, body });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
12
src/external-libraries/messageBroker.ts
Normal file
12
src/external-libraries/messageBroker.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { injectable } from "inversify";
|
||||
import logger from "../config/logger";
|
||||
import { IMessageBroker } from "../interfaces/IMessageBroker";
|
||||
|
||||
@injectable()
|
||||
export class MessageBroker implements IMessageBroker {
|
||||
async NotifyToPromotionService(product: unknown): Promise<boolean> {
|
||||
logger.debug("Message send ...", product);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
import "reflect-metadata"
|
||||
import app from "./app";
|
||||
import config from "./config/config";
|
||||
import { AppDataSource } from "./config/data-source";
|
||||
|
||||
@@ -1,20 +1,39 @@
|
||||
import { IMailer } from "../interfaces/IMailer";
|
||||
import { Product } from "../entities/Product";
|
||||
import { IProductInteractor } from "../interfaces/IProductInteractor";
|
||||
import { IProductRepository } from "../interfaces/IProductRepository";
|
||||
import { IMessageBroker } from "../interfaces/IMessageBroker";
|
||||
import { inject, injectable } from "inversify";
|
||||
import { INTERFACE_TYPE } from "../utils";
|
||||
|
||||
@injectable()
|
||||
export class ProductInteractor implements IProductInteractor {
|
||||
|
||||
private repository: IProductRepository
|
||||
private mailer: IMailer
|
||||
private broker: IMessageBroker
|
||||
|
||||
constructor(respository: IProductRepository) {
|
||||
this.repository = respository
|
||||
constructor(
|
||||
@inject(INTERFACE_TYPE.ProductRepository) repository: IProductRepository,
|
||||
@inject(INTERFACE_TYPE.Mailer) mailer: IMailer,
|
||||
@inject(INTERFACE_TYPE.MessageBroker) broker: IMessageBroker
|
||||
) {
|
||||
this.repository = repository
|
||||
this.mailer = mailer
|
||||
this.broker = broker
|
||||
}
|
||||
|
||||
async createProduct(input: never): Promise<Product> {
|
||||
return await this.repository.create(input)
|
||||
const data = await this.repository.create(input)
|
||||
// Do something notify promotion message
|
||||
await this.broker.NotifyToPromotionService(data)
|
||||
return data
|
||||
}
|
||||
async updateStock(id: number, stock: number): Promise<Product> {
|
||||
return await this.repository.update(id, { stock: stock })
|
||||
const data = await this.repository.update(id, { stock: stock })
|
||||
// Do some update Admin update a stock
|
||||
await this.mailer.SendMail("someone@gmail.com", "Update Stock", data)
|
||||
return data
|
||||
}
|
||||
async getProducts(limit: number, offset: number): Promise<Product[]> {
|
||||
return await this.repository.find(limit, offset)
|
||||
|
||||
3
src/interfaces/IMailer.ts
Normal file
3
src/interfaces/IMailer.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface IMailer {
|
||||
SendMail(to: string, subject: string, body: unknown): Promise<boolean>;
|
||||
}
|
||||
3
src/interfaces/IMessageBroker.ts
Normal file
3
src/interfaces/IMessageBroker.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export interface IMessageBroker {
|
||||
NotifyToPromotionService(product: unknown): Promise<boolean>;
|
||||
}
|
||||
@@ -3,7 +3,9 @@ import { AppDataSource } from "../config/data-source";
|
||||
import { Product } from "../entities/Product";
|
||||
import { IProductRepository } from "../interfaces/IProductRepository";
|
||||
import ApiError from "../utils/helper/ApiError";
|
||||
import { injectable } from "inversify";
|
||||
|
||||
@injectable()
|
||||
export class ProductRepository implements IProductRepository {
|
||||
private readonly productRepository: Repository<Product>;
|
||||
|
||||
|
||||
@@ -3,13 +3,36 @@ import { ProductController } from '../controllers/productController';
|
||||
import { ProductRepository } from '../repositories/productRepository';
|
||||
import { ProductInteractor } from '../interactors/productInteractor';
|
||||
import { IProductInteractor } from '../interfaces/IProductInteractor';
|
||||
import { Mailer } from '../external-libraries/mailer';
|
||||
import { MessageBroker } from '../external-libraries/messageBroker';
|
||||
import { Container } from 'inversify';
|
||||
import { IProductRepository } from '../interfaces/IProductRepository';
|
||||
import { INTERFACE_TYPE } from '../utils';
|
||||
import { IMailer } from '../interfaces/IMailer';
|
||||
import { IMessageBroker } from '../interfaces/IMessageBroker';
|
||||
|
||||
/**
|
||||
const repository = new ProductRepository()
|
||||
const mailer = new Mailer();
|
||||
const broker = new MessageBroker()
|
||||
const interactor: IProductInteractor = new ProductInteractor(repository, mailer, broker)
|
||||
const productController = new ProductController(interactor);
|
||||
|
||||
*/
|
||||
|
||||
const container = new Container();
|
||||
|
||||
container.bind<IProductRepository>(INTERFACE_TYPE.ProductRepository).to(ProductRepository);
|
||||
container.bind<IProductInteractor>(INTERFACE_TYPE.ProductInteractor).to(ProductInteractor);
|
||||
container.bind<IMailer>(INTERFACE_TYPE.Mailer).to(Mailer);
|
||||
container.bind<IMessageBroker>(INTERFACE_TYPE.MessageBroker).to(MessageBroker);
|
||||
container.bind(INTERFACE_TYPE.ProductController).to(ProductController);
|
||||
|
||||
const repository = new ProductRepository()
|
||||
const interactor: IProductInteractor = new ProductInteractor(repository)
|
||||
const productController = new ProductController(interactor);
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
const productController = container.get<ProductController>(INTERFACE_TYPE.ProductController);
|
||||
|
||||
router.post('/', productController.onCreateProduct.bind(productController));
|
||||
router.get('/', productController.onGetProducts.bind(productController));
|
||||
router.patch('/:id', productController.onUpdateStock.bind(productController));
|
||||
|
||||
7
src/utils/constant/appConstant.ts
Normal file
7
src/utils/constant/appConstant.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export const INTERFACE_TYPE = {
|
||||
ProductRepository: Symbol.for("ProductRepository"),
|
||||
ProductInteractor: Symbol.for("ProductInteractor"),
|
||||
ProductController: Symbol.for("ProductController"),
|
||||
Mailer: Symbol.for("Mailer"),
|
||||
MessageBroker: Symbol.for("MessageBroker"),
|
||||
}
|
||||
5
src/utils/index.ts
Normal file
5
src/utils/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from "./handler/async.handler";
|
||||
export * from "./handler/pick.handler";
|
||||
export * from "./helper/ApiError";
|
||||
export * from "./helper/ApiResponse"
|
||||
export * from "./constant/appConstant";
|
||||
Reference in New Issue
Block a user