068 Π Π°Π·Π±ΠΎΡ DI ΠΈ IOC
DI - dependency injection IOC - inversion of control
Π‘Π°ΠΌΠΎ ΡΠ²Π»Π΅Π½ΠΈΠ΅ Π²Π½Π΅Π΄ΡΠ΅Π½ΠΈΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ ΠΈΠ·Π±Π°Π²Π»ΡΠ΅Ρ Π½Π°Ρ ΠΎΡ ΠΏΠΎΡΡΠ΅Π±Π½ΠΎΡΡΠΈ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΠ° Π²Π½ΡΡΡΠΈ ΡΠ°ΠΌΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ°. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²Π½Π΅Π΄ΡΡΡΡ ΡΠ°Π·Π½ΡΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π» ΠΏΠΎ Π·Π°ΡΠ°Π½Π΅Π΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠΌΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ.
Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΡΠ°ΠΊ ΠΆΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΎΡΠ΄Π΅Π»ΠΈΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ, ΡΡΠΎΠ±Ρ Π΅Π³ΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ
Π‘ΠΎΠ²Π΅ΡΡΠΈΡΡ ΡΠ°ΠΌΠΎΠ΅ ΠΏΡΠΎΡΡΠΎΠ΅ Π²Π½Π΅Π΄ΡΠ΅Π½ΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ ΠΌΠΎΠΆΠ½ΠΎ:
- Π§Π΅ΡΠ΅Π· ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ
- ΠΠΈΠ±ΠΎ ΡΠ΅ΡΠ΅Π· ΠΌΠ΅ΡΠΎΠ΄
Composition root - ΡΡΠΎ ΠΎΠ΄Π½Π° ΡΠΎΡΠΊΠ°, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠΎΠ±ΠΈΡΠ°ΡΡΡΡ Π²ΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
ΠΡΠΎ ΡΡ Π΅ΠΌΠ° ΠΏΡΠΎΡΡΠΎΠ³ΠΎ DI, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ²ΡΠΎΡΠΈΡΡ Π² Π»ΡΠ±ΠΎΠΌ ΡΠ·ΡΠΊΠ΅
Π ΡΡΠΎ ΡΡ Π΅ΠΌΠ° Ρ ΡΠΈΠΏΠΈΠ·ΠΈΡΡΠ΅ΠΌΡΠΌΠΈ ΡΠ·ΡΠΊΠ°ΠΌΠΈ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΡΠΎΠΉ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ, ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ Π²Π½Π΅Π΄ΡΡΡΡ ΠΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π²ΡΡΡΡΠΏΠ°Π΅Ρ Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π½Π΅ΠΊΠΈΠΌ ΠΊΠΎΠ½ΡΡΠ°ΠΊΡΠΎΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΡΠΎ, ΡΡΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡΠΈΡΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅
Π Π²ΠΎΡ ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΠΎ Π½Π°Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΈΠ· ΡΠ΅Π±Ρ ΠΊΠΎΠ½ΡΡΠ°ΠΊΡ ΡΠΎΠ³ΠΎ, ΡΡΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡΠΈΡΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅
logger.interface.ts
import { Logger } from "tslog";
export interface ILogger {
logger: unknown;
log: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
warn: (...args: unknown[]) => void;
}
Π ΡΡΡ ΠΌΡ ΠΏΠΎ ΠΊΠΎΠ½ΡΡΠ°ΠΊΡΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΠ΄ΡΡ ΠΏΡΠΈΡΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ Π² ΠΊΠ»Π°ΡΡΠ΅ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ
logger.service.ts
import { Logger } from "tslog";
import { ILogger } from "./logger.interface";
export class LoggerService implements ILogger {
public logger: Logger<string>;
constructor() {
this.logger = new Logger();
}
log(...args: unknown[]) {
this.logger.info(...args);
}
error(...args: unknown[]) {
this.logger.error(...args);
}
warn(...args: unknown[]) {
this.logger.warn(...args);
}
}
Π ΡΠ΅ΠΏΠ΅ΡΡ Π² Π³Π»Π°Π²Π½ΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ Π²Ρ
ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ½ΡΡΠ°Π½Ρ Π½Π΅ Π½Π° ΡΠ°ΠΌ ΠΊΠ»Π°ΡΡ Π»ΠΎΠ³Π³Π΅ΡΠ°, Π° Π½Π° ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, ΠΊΠΎΡΠΎΡΠΎΠΌΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ΄ΠΎΠ²Π»Π΅ΡΠ²ΠΎΡΡΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΠΉ Π²Π½ΡΡΡΡ app
Π»ΠΎΠ³Π³Π΅Ρ
app.ts
export class App {
private app: Express;
private server: Server;
private port: number;
// ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ Π»ΠΎΠ³Π³Π΅Ρ ΠΏΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ
private logger: ILogger;
private userController: UserController;
private exceptionFilter: ExceptionFilter;
constructor(
// ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ Π»ΠΎΠ³Π³Π΅Ρ ΠΏΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ
logger: ILogger,
userController: UserController,
exceptionFilter: ExceptionFilter
) {
this.app = express();
this.port = 8000;
this.logger = logger;
this.userController = userController;
this.exceptionFilter = exceptionFilter;
}
// ΠΊΠΎΠ΄...
}
ΠΠ΅ΡΠ²ΡΠΉ ΠΏΡΠΈΠ½ΡΠΈΠΏ Π³ΠΎΠ²ΠΎΡΠΈΡ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ Π²ΡΠ΅ Π½Π°ΡΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ ΠΈΠ·ΠΎΠ»ΠΈΡΠΎΠ²Π°Π½Π½Ρ Π΄ΡΡΠ³ ΠΎΡ Π΄ΡΡΠ³Π°. Π‘Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ Π²ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΡΠ΅ΡΠ΅Π· Π°Π±ΡΡΡΠ°ΠΊΡΠΈΠΈ ΠΈ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΠΊΠΎΠ½ΡΡΠ°ΠΊΡ Π½Π° ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡΠΈΡΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ Π² Π΄ΡΡΠ³ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅:
ΠΡ ΡΠΎΠ·Π΄Π°Π»ΠΈ Π² ΠΊΠ»Π°ΡΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π»ΠΎΠ³Π³Π΅ΡΠ°, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΡΠΈΡΡΡΡΡΠ²ΠΎΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ: log
, error
ΠΈ warn
- ΡΠ°ΠΌ Π»ΠΎΠ³Π³Π΅Ρ ΠΌΡ Π½Π΅ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ, Π½ΠΎ Π² Π½ΡΠΌ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΎΠΏΠΈΡΠ°Π»ΠΈ Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ΅.
ΠΡΠΎΡΠΎΠΉ ΠΏΡΠΈΠ½ΡΠΈΠΏ Π³ΠΎΠ²ΠΎΡΠΈΡ Π½Π°ΠΌ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ Π½Π°ΠΌ Π½Π΅Π»ΡΠ·Ρ ΠΏΡΠΎΠΊΠΈΠ΄ΡΠ²Π°ΡΡ Π² Π±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π»ΠΊΠΈΠ΅ ΠΌΠΎΠ΄ΡΠ»ΠΈ (ΡΠ΅ ΠΆΠ΅ ΡΠ΅ΡΠ²ΠΈΡΡ) ΠΌΠΎΠ΄ΡΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ Π²ΡΡΠΎΠΊΠΎΠ³ΠΎ ΡΡΠΎΠ²Π½Ρ:
ΠΠ°ΠΌ Π½Π΅Π»ΡΠ·Ρ ΠΏΡΠΎΠΊΠΈΠ΄ΡΠ²Π°ΡΡ ΠΈΠ½ΡΡΠ°Π½Ρ app
Π²Π½ΡΡΡΡ ΡΠΎΠ³ΠΎ ΠΆΠ΅ exception
, logger
ΠΈΠ»ΠΈ router
.
ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ ΠΌΡ ΠΈΠΌΠ΅Π΅ΠΌ:
- ΠΡΠΈΠ½ΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ
- ΠΠ°ΡΡΠ΅ΡΠ½, ΠΏΠΎ ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΡΡΠΈ ΠΏΡΠΈΠ½ΡΠΈΠΏΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ
- Π ΡΠ°ΠΌΠ° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ
ΠΡΠΈ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½Π°Ρ ΠΊΠ»Π°ΡΡ Π ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΡΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅: ΠΌΡ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΠΌ, ΡΡΠΎ ΠΎΠ½ Π·Π°ΠΈΠ½ΡΡΠ°Π½ΡΠΈΠΈΡΠΎΠ²Π°Π½ ΠΈ ΡΡΠΎ ΠΎΠ½ ΡΠ΄ΠΎΠ²Π»Π΅ΡΠ²ΠΎΡΡΠ΅Ρ ΠΊΠ°ΠΊΠΎΠΌΡ-Π»ΠΈΠ±ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΡ Π’ΠΎ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ΅ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Ρ ΠΊΠ»Π°ΡΡΠΎΠΌ Π ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ - ΡΡΠΎ ΡΠ΅Π½ΡΡΠ°Π»ΡΠ½Π°Ρ ΡΠΎΡΠΊΠ° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π·Π° Π½Π°Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π½Π°ΡΠΈ ΠΊΠ»Π°ΡΡΡ, ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΎΠ½ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ, ΠΊΠ°ΠΊΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Π΅ΠΌΡ Π½ΡΠΆΠ½Ρ, ΡΠΎΠ·Π΄Π°ΡΡ ΡΡΠΈ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΈΡ Π²Π½ΡΡΡΡ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΌΡ ΠΈΠ·Π±Π°Π²Π»ΡΠ΅ΠΌΡΡ ΠΎΡ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Agregation Root - ΡΠ΅ΠΏΠ΅ΡΡ ΠΎΠ½ ΡΠΎΠ·Π΄Π°ΡΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΈ Π΅Π³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΎΡ Π½Π°Ρ ΡΠΊΡΡΡΠ°, ΡΡΠΎ ΡΠΏΡΠΎΡΠ°Π΅Ρ Π½Π°Ρ DI, ΡΠΌΠ΅Π½ΡΡΠ°Ρ ΡΡΡΠΎΡΠΊΠΈ Π½ΡΠΆΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°
Π’Π°ΠΊ ΠΆΠ΅ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅ ΠΎΠ±ΡΡΠ½ΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΡΡΡ ΡΠ΅ΡΠ²ΠΈΡ Π»ΠΎΠΊΠ°ΡΠΎΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΌΡ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅ΠΌ Π²ΡΠ΅ Π½Π°ΡΠΈ ΡΠ΅ΡΠ²ΠΈΡΡ, Π° ΠΏΠΎΡΠΎΠΌ ΡΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΡΠ°ΡΠΈΡΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΠΉ ΠΈΠ½ΡΡΠ°Π½Ρ ΡΡΠΎΠ³ΠΎ ΡΠ΅ΡΠ²ΠΈΡΠ°, ΡΡΠΎΠ±Ρ Π΅Π³ΠΎ Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π’Π°ΠΊΠΎΠΉ ΠΏΠ°ΡΡΠ΅ΡΠ½ Π½Π΅ ΡΡΠΎΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΠΉ ΡΠ°Π±ΠΎΡΠ΅ - ΡΡΠΎ ΠΏΡΠΎΡΡΠΎ ΡΡ ΠΎΠΆΠ΅ΡΡΡ Ρ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π² Π΄Π°Π½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅ - Π² Π½Π°ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΡΡΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π΄Π»Ρ ΡΠ΅ΡΡΠΎΠ² ΠΈ Π·Π°ΠΏΡΡΠΊΠ° ΡΠ°ΠΌΠΎΠ³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
069 ΠΠ΅ΠΊΠΎΡΠ°ΡΠΎΡΡ
ΠΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠ°Ρ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ ΡΡΡ: ΠΠ΅ΠΊΠΎΡΠ°ΡΠΎΡΡ
Π‘Π°ΠΌ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΈΠ· ΡΠ΅Π±Ρ ΠΎΠ±ΡΡΡΠΊΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ ΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ, Π½Π°Π΄ ΠΊΠΎΡΠΎΡΡΠΌ Π±ΡΠ΄ΡΡ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΡΡΡΡ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΡΡΠΈΠΈ ΠΈ Π΄Π°Π»Π΅Π΅ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΡΠ΅Ρ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°
ΠΠ΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΊΠ»Π°ΡΡΠ°. ΠΠ½ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ ΡΠ°ΡΠ³Π΅Ρ - ΡΠ°ΠΌ ΠΊΠ»Π°ΡΡ ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΡΡΠΈΠΈ Π½Π°Π΄ ΠΊΠ»Π°ΡΡΠΎΠΌ ΠΈΠ»ΠΈ ΠΆΠ΅ ΠΏΡΠΎΡΡΠΎ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΡ ΡΡΠΎ-ΡΠΎ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΠΊΠ»Π°ΡΡΠΎΠΌ.
function Component(target: Function) {
console.log(target);
}
@Component
export class User {
id: number;
updateId(newId: number): number {
this.id = newId;
return this.id;
}
}
Π ΡΡΠΎΠ±Ρ ΠΌΡ ΠΌΠΎΠ³Π»ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π° Π½Π°ΡΠ΅Π³ΠΎ ΠΊΠ»Π°ΡΡΠ°, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΠΈ Π²Π΅ΡΠ½ΡΡΡ Π΅Ρ ΠΆΠ΅ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ, Π½ΠΎ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°Π½Π½ΡΡ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π½ΠΈΠΆΠ΅ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅.
Π’ΡΡ ΠΌΡ ΠΏΠΎΠΌΠ΅Π½ΡΠ»ΠΈ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΊΠ»Π°ΡΡΠ° Π½Π° ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΠΎΠ΅ Π² Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ. ΠΠ΅ΠΊΠΎΡΠ°ΡΠΎΡ ΡΠ°ΠΊ ΠΆΠ΅ ΡΠ΅ΠΉΡΠ°Ρ Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ Π½Π΅ ΡΠ΅ΡΠ΅Π· @Component
, Π° ΡΠ΅ΡΠ΅Π· @Component(Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅)
function Component(id: number) {
console.log("init");
return (target: Function) => {
console.log("run");
target.prototype.id = id;
};
}
@Component(1)
export class User {
id: number;
updateId(newId: number): number {
this.id = newId;
return this.id;
}
}
console.log(new User().id);
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΠΎΡΠ°ΡΠΈΠ²Π°ΡΡ Π½Π°ΡΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΡΠ°Π·Ρ Π² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠΎΠ². ΠΡΠ΄Π΅Ρ ΠΈΠ΄ΡΠΈ ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠ½ΠΈΠ·Ρ Π²Π²Π΅ΡΡ Π² ΡΠ»ΡΡΠ°Π΅ ΠΊΠ»Π°ΡΡΠΎΠ². Π ΠΎΡΡΠ°Π»ΡΠ½ΡΡ ΡΠ»ΡΡΠ°ΡΡ - ΡΠ²Π΅ΡΡ Ρ Π²Π½ΠΈΠ·
function Component(id: number) {
console.log("init Component");
return (target: Function) => {
console.log("run Component");
target.prototype.id = id;
};
}
function Logger() {
console.log("init Logger");
return (target: Function) => {
console.log("run Logger");
};
}
@Logger()
@Component(1)
export class User {
id: number;
updateId(newId: number): number {
this.id = newId;
return this.id;
}
}
console.log(new User().id);
ΠΠ΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ². Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΠ²ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π»ΠΎΠ³ΠΈΠΊΡ ΡΠ°Π±ΠΎΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Π²Π½ΡΡΡΠΈ ΠΊΠ»Π°ΡΡΠΎΠ². ΠΠ΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΈΠ·Π½Π°ΡΠ°Π»ΡΠ½ΡΡ ΡΠ°Π±ΠΎΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° ΠΈ ΠΏΡΠΎΡΡΠΎ Π΅Ρ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΡ, Π»ΠΈΠ±ΠΎ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π²ΠΎΠ²ΡΠ΅.
// ΠΊΠΎΠ΄ ...
// ΡΡΠΎ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄Π°
function Method(
// ΡΠ°ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ
target: Object,
// ΠΈΠΌΡ ΠΌΠ΅ΡΠΎΠ΄Π°
propertyKey: string,
propertyDescriptor: PropertyDescriptor
) {
// ΡΡΡ Π²ΡΠ²ΠΎΠ΄ΠΈΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Π°
console.log(propertyKey);
// ΡΡΡ ΠΌΡ ΡΠΎΡ
ΡΠ°Π½ΡΠ΅ΠΌ ΡΡΠ°ΡΡΠΉ ΠΌΠ΅ΡΠΎΠ΄
const oldValue = propertyDescriptor.value;
// ΡΡΡ ΡΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ ΡΠ°Π±ΠΎΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ
propertyDescriptor.value = function (...args: unknown[]) {
// oldValue(); // ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΠ·Π²Π°ΡΡ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄
// ΡΠΌΠ½ΠΎΠΆΠΈΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠΉ id Π½Π° 10, Π΅ΡΠ»ΠΈ ΠΎΠ½ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΈΡΠ»ΠΎΠΌ
if (typeof args[0] === "number") {
return args[0] * 10;
}
return args;
};
}
@Logger()
@Component(1)
export class User {
id: number;
@Method
updateId(newId: number): number {
this.id = newId;
return this.id;
}
}
console.log(new User().id);
console.log(new User().updateId(2)); // 20
Π’ΡΡ ΡΠΆΠ΅ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π° ΡΠ°Π±ΠΎΡΠ° Π²ΡΠ΅Ρ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠΎΠ², Π²ΠΊΠ»ΡΡΠ°Ρ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΡ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΠΌΠ΅ΡΠΎΠ΄Π°
ΠΏΠΎΠ»Π½ΡΠΉ Π»ΠΈΡΡΠΈΠ½Π³
// ΠΠ΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΊΠ»Π°ΡΡΠ°
function Component(id: number) {
console.log("init Component");
// ΡΡΠΎΠ±Ρ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΠ°, Π½ΡΠΆΠ½ΠΎ Π²Π΅ΡΠ½ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ ΡΡΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ°
return (target: Function) => {
console.log("run Component");
// ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π²ΠΎ Π²Π½ΡΡΡΠ΅Π½Π½Π΅Π΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ ΠΊΠ»Π°ΡΡΠ°
target.prototype.id = id;
};
}
// ΡΡΠΎ Π²ΡΠΎΡΠΎΠΉ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΊΠ»Π°ΡΡΠ° - Π»ΠΎΠ³Π³Π΅Ρ
function Logger() {
console.log("init Logger");
// Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΡΠ°ΠΌ ΠΊΠ»Π°ΡΡ ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΡ Π»ΠΎΠ³
return (target: Function) => {
console.log("run Logger");
};
}
// ΡΡΠΎ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄Π°
function Method(
// ΡΠ°ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡ
target: Object,
// ΠΈΠΌΡ ΠΌΠ΅ΡΠΎΠ΄Π°
propertyKey: string,
propertyDescriptor: PropertyDescriptor
) {
// ΡΡΡ Π²ΡΠ²ΠΎΠ΄ΠΈΠΌ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Π°
console.log(propertyKey);
// ΡΡΡ ΠΌΡ ΡΠΎΡ
ΡΠ°Π½ΡΠ΅ΠΌ ΡΡΠ°ΡΡΠΉ ΠΌΠ΅ΡΠΎΠ΄
const oldValue = propertyDescriptor.value;
// ΡΡΡ ΡΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ ΡΠ°Π±ΠΎΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ
propertyDescriptor.value = function (...args: unknown[]) {
// oldValue(); // ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΠ·Π²Π°ΡΡ ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄
// ΡΠΌΠ½ΠΎΠΆΠΈΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠΉ id Π½Π° 10, Π΅ΡΠ»ΠΈ ΠΎΠ½ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΈΡΠ»ΠΎΠΌ
if (typeof args[0] === "number") {
return args[0] * 10;
}
return args;
};
}
// Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ Π΄Π»Ρ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΠ°
function Prop(target: Object, propertyKey: string) {
let value: number;
// Π³Π΅ΡΡΠ΅Ρ Π΄Π»Ρ ΠΏΡΠΎΠΏΠ΅ΡΡΠΈ
const getter = () => {
console.log("get");
return value;
};
// ΡΠ΅ΡΡΠ΅Ρ Π΄Π»Ρ ΠΏΡΠΎΠΏΠ΅ΡΡΠΈ
const setter = (newValue: number) => {
console.log("set");
value = newValue;
};
// ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ Π³Π΅ΡΡΠ΅Ρ ΠΈ ΡΠ΅ΡΡΠ΅Ρ Π΄Π»Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
});
}
// Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ Π΄Π»Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΠΈ
function Param(
target: Object,
propertyKey: string,
// ΠΈΠ½Π΄Π΅ΠΊΡ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΠΈ
index: number
) {
console.log(propertyKey, index);
}
@Logger() // ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ Π²ΡΠΎΡΡΠΌ
@Component(1) // ΡΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΠΏΠ΅ΡΠ²ΡΠΌ
export class User {
// Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ ΡΠ²ΠΎΠΉΡΡΠ²Π°
@Prop id: number;
// Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄Π° + Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° ΠΌΠ΅ΡΠΎΠ΄Π°
@Method
updateId(@Param newId: number): number {
this.id = newId;
return this.id;
}
}
console.log(new User().id);
console.log(new User().updateId(2)); // 20
ΠΡΠΎ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ Π΄Π»Ρ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠ»Π°ΡΡΠ°
Π ΡΡΡ ΡΠ°Π±ΠΎΡΠ° Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠ° Π΄Π»Ρ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ° ΠΌΠ΅ΡΠΎΠ΄Π°
070 Metadata Reflection
ΠΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡ Ρ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ
Π½Π°ΡΠΈΡ
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Reflect
.
Π Π½Π΅ΠΉ ΠΏΡΠΈΡΡΡΡΡΠ²ΡΠ΅Ρ ΠΌΠ΅ΡΠΎΠ΄ defineMetadata()
, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΠΊΠ»ΡΡ Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΊ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠΌΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ.
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ getMetadata()
ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎ ΡΡΠΎΠΌΡ ΠΊΠ»ΡΡΡ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΌΠ΅ΡΠ°ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΏΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΡ
Π’Π°ΠΊ ΠΌΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ
npm i reflect-metadata
Π’Π°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°
import "reflect-metadata";
function Test(target: Function) {
// ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΡΠ°Π΄Π°ΡΡ ΠΏΠΎΠ΄ ΠΊΠ»ΡΡΠΎΠΌ "a" Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ 1 ΠΏΠΎΠ΄ Π½Π°ΡΠΈΠΌ ΠΊΠ»Π°ΡΡΠΎΠΌ
Reflect.defineMetadata("a", 1, target);
// ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ
ΠΏΠΎΠ΄ ΠΊΠ»ΡΡΠΎΠΌ "a" ΠΎΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΊΠ»Π°ΡΡΠ°
const meta = Reflect.getMetadata("a", target);
console.log(meta);
}
@Test
export class C {}
ΠΠΊΡΠΏΠ΅ Ρ ΡΡΠΎΠΉ Π½Π°ΡΡΡΠΎΠΉΠΊΠΎΠΉ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ° Π’Π‘, Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠΈΡΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΡΠΈΠΏΠΎΠ² ΠΈ Π² Π½Π°Ρ ΡΠ°Π½ΡΠ°ΠΉΠΌ (Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΏΠΎΡΠ»Π΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ)
tsconfig.json
"emitDecoratorMetadata": true,
ΠΡ ΠΈ ΡΠ΅ΠΉΡΠ°Ρ Π½ΡΠΆΠ½ΠΎ ΠΎΠ±ΡΡΡΠ½ΠΈΡΡ ΡΠ²ΡΠ·Ρ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠΎΠ² ΠΈ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ . ΠΠ΅Π»ΠΎ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΠ·Π²Π°ΡΡ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΡ ΠΏΠΎΠ΄ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΠΈΠ½ΡΡΠ°Π½Ρ ΠΊΠ»Π°ΡΡΠ° ΠΈ Π΄Π΅Π»Π°ΡΡ DI Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²ΡΠ·ΠΎΠ²Π° Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΠ½Π΄ΠΆΠ΅ΠΊΡΠΈΡ ΠΈΠ½ΡΡΠ°Π½Ρ ΠΊΠ»Π°ΡΡΠ° ΠΏΡΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠΈ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠΎΠΌ Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ°. Π’ΠΎ Π΅ΡΡΡ ΠΈΠ΄ΡΡ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅ ΠΊΠ»Π°ΡΡΠΎΠ² Π΄ΡΡΠ³ Ρ Π΄ΡΡΠ³ΠΎΠΌ ΡΠ΅ΡΠ΅Π· ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΠ΅, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΎΡ ΡΠ°Π½ΡΡΡΡΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡΠ°, Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΠ΄ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΠ° ΠΈΠ»ΠΈ ΠΏΠΎΠ΄ ΠΊΠ»Π°ΡΡ.
import "reflect-metadata";
// Pseudocode
function Injectable(key: string) {
return (target: Function) => {
Reflect.defineMetadata(key, 1, target);
const meta = Reflect.getMetadata(key, target);
console.log(meta);
};
}
function Inject(key: string) {}
function Prop(target: Object, name: string) {}
// ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ°Π΅ΠΌ ΠΊΠ»Π°ΡΡ "C"
@Injectable("C")
export class C {
@Prop prop: number;
}
// ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ°Π΅ΠΌ ΠΊΠ»Π°ΡΡ "D"
@Injectable("D")
export class D {
// ΡΡΡ ΠΈΠ΄ΡΡ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅ ΠΈΠ½ΡΡΠ°Π½ΡΠ° ΠΊΠ»Π°ΡΡΠ° "C" Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ Π² ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡ
constructor(@Inject('C') c: C) {}
}
071 ΠΠ½Π΅Π΄ΡΡΠ΅ΠΌ InversifyJS
Π ΠΏΠ΅ΡΠ²ΡΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ, Π½ΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ inversify
Π² ΠΏΡΠΎΠ΅ΠΊΡ
npm i inversify
Π’ΡΡ Π±ΡΠ΄ΡΡ Ρ ΡΠ°Π½ΠΈΡΡΡΡ ΡΠΈΠΌΠ²ΠΎΠ»Ρ, ΠΏΠΎ ΠΊΠΎΡΠΎΡΡΠΌ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡΡ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅ Π½Π°ΡΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ² Π²Π½ΡΡΡΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°
types.ts
export const TYPES = {
Application: Symbol.for('Application'),
ILogger: Symbol.for('ILogger'),
UserController: Symbol.for('UserController'),
ExceptionFilter: Symbol.for('ExceptionFilter'),
};
ΠΠ°Π»Π΅Π΅ Π² ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΊΠΎΠ½Π΅Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ, Π²Π½ΡΡΡΠΈ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡΡ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΠ΅ ΠΊΠ»Π°ΡΡΠ° Ρ Π΅Π³ΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ (Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π²ΡΡΡΡΠΏΠ°Π΅Ρ ΡΠΈΠΌΠ²ΠΎΠ» TYPES
)
main.ts
// ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ - ΡΡΠΎ ΠΊΠΎΡΠΎΠ±ΠΊΠ°, Π² ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ Π²ΠΊΠ»Π°Π΄ΡΠ²Π°ΡΡ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΈ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² Π½Π° ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ, Π° ΠΏΠΎΡΠΎΠΌ Π±ΡΠ΄Π΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
const appContainer = new Container();
// Π’ΡΡ ΡΠΆΠ΅ Π±ΡΠ΄ΡΡ Π»Π΅ΠΆΠ°ΡΡ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΈ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΠΌΡ Ρ
ΠΎΡΠΈΠΌ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ
// Π’ΡΡ ΠΌΡ ΡΠΊΠ°Π·Π°Π»ΠΈ, ΡΡΠΎ Π΄Π»Ρ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ILogger Π±ΡΠ΄Π΅Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΎΠ²Π°ΡΡ LoggerService ΡΠ΅ΡΠ΅Π· ΡΠΈΠΌΠ²ΠΎΠ» TYPES.ILogger
appContainer.bind<ILogger>(TYPES.ILogger).to(LoggerService);
appContainer.bind<IExceptionFilter>(TYPES.ExceptionFilter).to(ExceptionFilter);
appContainer.bind<UserController>(TYPES.UserController).to(UserController);
appContainer.bind<App>(TYPES.Application).to(App);
// Π’ΡΡ ΡΠΆΠ΅ ΠΌΡ Π΄ΠΎΡΡΠ°ΡΠΌ ΠΈΠ· ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° Π½Π°Ρ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ App
const app = appContainer.get<App>(TYPES.Application);
app.init();
export { app, appContainer };
Π’Π°ΠΊ ΠΆΠ΅ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΡ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ΄ΡΡΠ°Π²ΠΈΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π΄ΠΆΠ΅Π½Π΅ΡΠΈΠΊΠ° Π½Π΅ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, Π° ΡΠ°ΠΌ ΠΊΠ»Π°ΡΡ, Π΅ΡΠ»ΠΈ ΠΌΡ ΠΏΠΎΠ΄ΡΠ°Π·ΡΠΌΠ΅Π²Π°Π΅ΠΌ, ΡΡΠΎ ΡΠΈΠ»ΡΡΡΡ Π±ΡΠ΄ΡΡ ΠΈΠ΄ΡΠΈ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌΠΈ.
// Π’ΡΡ ΡΠΆΠ΅ Π²ΠΌΠ΅ΡΡΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΡΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ExceptionFilter Π΄Π»Ρ ΡΠ²ΡΠ·ΡΠ²Π°Π½ΠΈΡ
appContainer
.bind<ExceptionFilter>(TYPES.ExceptionFilter)
.to(ExceptionFilter);
ΠΠ°Π»Π΅Π΅ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ ΠΈΠ½ΠΆΠ΅ΠΊ Π²ΡΠ΅Ρ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ ΠΎΡ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ ΠΏΠΎΠΏΠ°Π»ΠΈ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΠΈ Π΄ΠΎ Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ Π΄ΠΎΡΡΡΡΠ°ΡΡΡΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° ΠΈΠ½Π²Π΅ΡΡΠΈΡΠ°Ρ
logger.service.ts
// Π΄Π°Π½Π½ΡΠΉ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ Π³ΠΎΠ²ΠΎΡΠΈΡ, ΡΡΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΡ Π΄Π°Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ
// ΡΠΎ Π΅ΡΡΡ ΠΏΠΎΠΊΠ° ΠΌΡ Π½Π΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π»ΠΈ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ, ΡΠΎ ΠΌΡ Π½Π΅ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΠΌ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΡΠ²ΡΠ·ΠΈ Ρ ΡΠΈΠΌΠ²ΠΎΠ»Π°ΠΌΠΈ
@injectable()
export class LoggerService implements ILogger {
public logger: Logger<string>;
// code ...
Π’Π°ΠΊ ΠΆΠ΅ Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ ΠΈΠ½ΠΆΠ΅ΠΊΡ Π²ΡΠ΅Ρ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠ΅ΠΉ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ Π΄ΠΎΡΡΡΠΏΠ½Ρ Π²Π½ΡΡΡΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°
exception.filter.ts
import 'reflect-metadata';
@injectable()
export class ExeptionFilter implements IExeptionFilter {
// inject - ΡΡΠΎ Π΄Π΅ΠΊΠΎΡΠ°ΡΠΎΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΡΠΎ, ΡΡΠΎ Π½ΡΠΆΠ½ΠΎ Π·Π°ΠΈΠ½Π΄ΠΆΠ΅ΠΊΡΠΈΡΡ
constructor(@inject(TYPES.ILogger) private logger: ILogger) { }
// code...
Π’Π°ΠΊ ΠΆΠ΅ Π½ΡΠΆΠ½ΠΎ ΡΠΏΠΎΠΌΡΠ½ΡΡΡ, ΡΡΠΎ ΠΈΠΌΠ΅Π½Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΠΈ ΠΊΠ»Π°ΡΡΠΎΠ² Π½Π΅ ΡΡΠΎΠΈΡ ΠΏΠΎΠ²ΡΠΎΡΡΡΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡΡ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠΎΠ²Π°ΡΡ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅
users.controller.ts
@injectable()
export class UserController extends BaseController {
// ΠΌΠ΅Π½ΡΠ΅ΠΌ ΠΈΠΌΡ logger Π½Π° loggerService, ΡΡΠΎΠ±Ρ Π½Π΅ Π±ΡΠ»ΠΎ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡΠΎΠ² Π²Π½ΡΡΡΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°
constructor(@inject(TYPES.ILogger) private loggerService: ILogger) {
super(loggerService);
this.bindRoutes([
{
path: "/register",
method: "post",
func: this.register,
},
{
path: "/login",
method: "post",
func: this.login,
},
]);
}
// code ...
base.controller.ts
// ΡΡΠΎΡ ΠΊΠ»Π°ΡΡ Π½ΡΠΆΠ½ΠΎ ΡΠ°ΠΊ ΠΆΠ΅ Π·Π°ΠΈΠ½Π΄ΠΆΠ΅ΠΊΡΠΈΡΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΈΠΌ ΡΠ°ΡΡΠΈΡΡΠ΅ΡΡΡ users.controller
@injectable()
export abstract class BaseController {
private readonly _router: Router;
constructor(private logger: ILogger) {
this._router = Router();
}
// code ...
Π Π² ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΠΊΠ»Π°ΡΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π½ΡΠΆΠ½ΠΎ ΡΠ°ΠΊ ΠΆΠ΅ Π·Π°ΠΈΠ½ΠΆΠ΅ΠΊΡΠΈΡΡ Π²ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΈ ΡΠ°ΠΌ ΠΊΠ»Π°ΡΡ
app.ts
// Π΄Π΅Π»Π°Π΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΠΊΠ»Π°ΡΡ ΡΠΎΠΆΠ΅ Π²Π½Π΅Π΄ΡΡΠ΅ΠΌΡΠΌ
@injectable()
export class App {
app: Express;
server: Server;
port: number;
constructor(
// Π ΡΡΡ ΠΌΠ΅Π½ΡΠ΅ΠΌ Π²ΡΠ΅ Π½Π°ΡΠΈ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π΄Π΅ΠΊΠΎΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ
@inject(TYPES.ILogger) private logger: ILogger,
@inject(TYPES.UserController) private userController: UserController,
@inject(TYPES.ExceptionFilter) private exceptionFilter: ExceptionFilter
) {
this.app = express();
this.port = 8000;
}
// code ...
common > base.controller.ts
export abstract class BaseController {
private readonly _router: Router;
// ΠΠ΄Π΅ΡΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ ILogger
constructor(private logger: ILogger) {
this._router = Router();
}
// code ...
ΠΠ°Π»Π΅Π΅, ΡΡΠΎΠ±Ρ Π²ΡΡ Π·Π°ΡΠ°Π±ΠΎΡΠ°Π»ΠΎ, Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π΄Π°Π½Π½ΡΠΉ ΠΈΠΌΠΏΠΎΡΡ Π²ΠΎ Π²ΡΠ΅ ΡΠ°ΠΉΠ»Ρ, Π² ΠΊΠΎΡΠΎΡΡΡ
Π±ΡΠ» ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ inject
ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ inversify
import 'reflect-metadata';
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ.
ΠΡΠΎΠ³:
- Π ΠΈΡΠΎΠ³Π΅ ΠΌΡ Π·Π°ΠΌΠ΅Π½ΠΈΠ»ΠΈ Π½Π°Ρ DI Π½Π° ΡΡΡΠ½ΠΎΠΉ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ°.
- ΠΡΠ½ΠΎΠ²Π½ΡΠΌ ΠΏΠ»ΡΡΠΎΠΌ ΡΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ ΠΎΠ΄Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΎ, ΡΡΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π² Π»ΡΠ±ΠΎΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π»ΡΠ±ΠΎΠΉ ΠΈΠ½ΡΡΠ°Π½Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ° ΡΠ΅ΡΠ΅Π·
get
.- ΠΡΠ»ΠΈ Ρ Π½Π°Ρ Π³Π΄Π΅-ΡΠΎ ΠΏΠΎΡΠ²ΠΈΡΡΡ Π½ΠΎΠ²ΡΠΉ Π½Π΄ΠΆΠ΅ΠΊΡΡΠ±Π», ΡΠΎ Π½Π°ΠΌ Π½Π΅ ΠΏΡΠΈΠ΄ΡΡΡΡ Π΅Π³ΠΎ ΠΏΡΠΎΠΊΠΈΠ΄ΡΠ²Π°ΡΡ Π²ΡΡΡΠ½ΡΡ. ΠΠ°ΠΌ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π· ΡΠ΄Π΅Π»Π°ΡΡ
bind
ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° ΠΈ Π² ΡΠΎΠΌ ΠΌΠ΅ΡΡΠ΅, Π³Π΄Π΅ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ΄ΡΡΠ°Π²ΠΈΡΡ ΡΠΈΠΏ, ΠΌΡ ΡΠΌΠΎΠΆΠ΅ΠΌ Π΅Π³ΠΎ ΠΏΠΎΠ΄ΡΡΠ°Π²ΠΈΡΡ ΡΠ΅ΡΠ΅Π·@inject(TYPES.ΡΠΈΠΏ)
- Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ Π»Π΅Π³ΠΊΠΎ ΠΌΠ΅Π½ΡΡΡ ΡΠ΅ΡΠ²ΠΈΡΡ - Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ Π΅Π³ΠΎ Π²
.to(Π‘Π΅ΡΠ²ΠΈΡ)
ΠΈ Ρ Π½Π°Ρ Π²ΡΡ Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ.
072 Π£ΠΏΡΠ°ΠΆΠ½Π΅Π½ΠΈΠ΅ - Π£Π»ΡΡΡΠ°Π΅ΠΌ DI
ΠΠ°Π»Π΅Π΅ Π½Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ ΡΠΈΠ»ΡΠ½ΠΎ ΡΠ°Π·ΡΠ°ΡΡΠΈΡΡ ΠΈ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΎΠ² Π±ΡΠ΄Π΅Ρ Π²ΡΡ ΠΎΠ΄ΠΈΡΡ Π·Π° ΡΠ°ΠΌΠΊΠΈ 30 ΠΈ 40 ΡΡΡΠΊ. ΠΠ»Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ Π±ΠΎΠ»ΡΡΠΈΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎΠΌ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΎΠ², ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ, Π±ΡΠ» ΠΏΡΠΈΠ΄ΡΠΌΠ°Π½ ΠΌΠΎΠ΄ΡΠ»Ρ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°
main.ts
appContainer.bind<ILogger>(TYPES.ILogger).to(LoggerService);
appContainer.bind<IExeptionFilter>(TYPES.ExeptionFilter).to(ExeptionFilter);
appContainer.bind<UserController>(TYPES.UserController).to(UserController);
appContainer.bind<App>(TYPES.Application).to(App);
ΠΠΎΡ ΡΠ°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡΠ° Ρ ΡΠΎΠ±ΡΠ°Π½Π½ΡΠΌΠΈ Π±ΠΈΠ½Π΄ΠΈΠ½Π³Π°ΠΌΠΈ. Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΡΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΈ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΈ, ΡΡΠΎΠ±Ρ Π½Π΅ Ρ ΡΠ°Π½ΠΈΡΡ ΠΈΡ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅, Π° ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΏΠΎ ΠΏΡΠΎΠ΅ΠΊΡΡ ΠΈ ΡΠ΄ΠΎΠ±Π½ΠΎ ΡΠ°Π·Π΄Π΅Π»ΡΡΡ ΠΈΡ , ΡΡΠΎΠ±Ρ Π² Π±ΡΠ΄ΡΡΠ΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΡΠ΄ΠΎΠ±Π½ΠΎ ΡΠ°Π·Π»ΠΈΡΠ°ΡΡ ΠΈΡ ΠΈ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ
main.ts
// ΠΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ²Π΅ΡΡΠ°ΡΡ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΈ ΠΈΠ½Π²Π΅ΡΡΠΈΡΠ°Ρ
export const appBindings = new ContainerModule((bind: interfaces.Bind) => {
bind<ILogger>(TYPES.ILogger).to(LoggerService);
bind<IExeptionFilter>(TYPES.ExeptionFilter).to(ExeptionFilter);
bind<UserController>(TYPES.UserController).to(UserController);
bind<App>(TYPES.Application).to(App);
});
function bootstrap() {
const appContainer = new Container();
// ΡΠΆΠ΅ ΡΡΡ ΠΌΡ ΠΏΡΠΎΡΡΠΎ Π·Π°Π³ΡΡΠ·ΠΈΠΌ Π²ΡΠ΅ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π»ΠΈ ΡΠ°Π½Π΅Π΅
appContainer.load(appBindings);
const app = appContainer.get<App>(TYPES.Application);
app.init();
// Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌ ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
return { app, appContainer };
}
// ΡΠΊΡΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅, ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠ΅ ΠΈΠ· ΡΡΠ½ΠΊΡΠΈΠΈ
export const { app, appContainer } = bootstrap();
Π Π΄Π°Π»Π΅Π΅ Π½ΡΠΆΠ½ΠΎ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ»ΡΡΡΠΈΡΡ Π½Π°Ρ DI ΠΈ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΄Π»Ρ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ. ΠΠ½ Π±ΡΠ΄Π΅Ρ ΠΈΠΌΠ΅ΡΡ Π»ΠΎΠ³ΠΈΠ½ ΠΈ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΡ.
users.controller.interface.ts
import { NextFunction, Request, Response } from 'express';
export interface IUserController {
login: (req: Request, res: Response, next: NextFunction) => void;
register: (req: Request, res: Response, next: NextFunction) => void;
}
Π ΡΠ°ΠΌΠΎΠΌ ΠΊΠΎΠ½ΡΡΠΎΠ»Π»Π΅ΡΠ΅ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΡΠΊΡΡΠ΅Π½Π΄ΠΎΠΌ ΠΎΡ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ Π΅ΡΡ ΠΈ Π·Π°ΠΈΠΌΠΏΠ»Π΅ΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΎΡ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ°. Π§ΡΠΎΠ±Ρ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΡΠ΄Π΅Π»Π°ΡΡ ΠΈ ΡΠΎ, ΠΈ ΡΠΎ, Π½ΡΠΆΠ½ΠΎ ΡΠ½Π°ΡΠ°Π»Π° ΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ extends
, Π° ΡΠΆΠ΅ ΠΏΠΎΡΠΎΠΌ implements
users.controller.ts
// imports...
import { IUserController } from './users.controller.interface';
@injectable()
export class UserController extends BaseController implements IUserController {
constructor(
@inject(TYPES.ILogger) private loggerService: ILogger
) {
super(loggerService);
this.bindRoutes([
{ path: '/register', method: 'post', func: this.register },
{ path: '/login', method: 'post', func: this.login },
])
}
login(req: Request, res: Response, next: NextFunction) {
next(new HTTPError(401, 'ΠΎΡΠΈΠ±ΠΊΠ° Π°Π²ΡΠΎΡΠΈΠ·Π°ΡΠΈΠΈ', 'login'));
}
register(req: Request, res: Response, next: NextFunction) {
this.ok(res, 'register');
}
}