|
@@ -8,7 +8,6 @@
|
|
|
## Содержание
|
|
## Содержание
|
|
|
|
|
|
|
|
- [Установка](#Установка)
|
|
- [Установка](#Установка)
|
|
|
-- [Мотивация](#Мотивация)
|
|
|
|
|
- [Описание](#Описание)
|
|
- [Описание](#Описание)
|
|
|
- [Базовые примеры](#Базовые-примеры)
|
|
- [Базовые примеры](#Базовые-примеры)
|
|
|
- [ServiceContainer](#ServiceContainer)
|
|
- [ServiceContainer](#ServiceContainer)
|
|
@@ -38,157 +37,6 @@ import {Service} from '@e22m4u/js-service';
|
|
|
const {Service} = require('@e22m4u/js-service');
|
|
const {Service} = require('@e22m4u/js-service');
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-## Мотивация
|
|
|
|
|
-
|
|
|
|
|
-При росте проекта, построенного на классах, разработчики часто сталкиваются
|
|
|
|
|
-с проблемой управления зависимостями. Классы начинают зависеть друг от друга,
|
|
|
|
|
-и для их совместной работы требуется где-то создавать экземпляры и передавать
|
|
|
|
|
-их в конструкторы или методы других классов. Ручное внедрение зависимостей
|
|
|
|
|
-быстро приводит к сложному и запутанному коду.
|
|
|
|
|
-
|
|
|
|
|
-#### Проблема: Ручное управление зависимостями
|
|
|
|
|
-
|
|
|
|
|
-Представим типичную ситуацию - есть сервис для работы с пользователями
|
|
|
|
|
-`UserService`, который нуждается в логгере `Logger` и клиенте для доступа
|
|
|
|
|
-к базе данных `DatabaseClient`.
|
|
|
|
|
-
|
|
|
|
|
-Без библиотеки это может выглядеть так:
|
|
|
|
|
-
|
|
|
|
|
-```js
|
|
|
|
|
-// зависимости
|
|
|
|
|
-class Logger {
|
|
|
|
|
- log(message) {
|
|
|
|
|
- console.log(message);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-class DatabaseClient {
|
|
|
|
|
- query(id) {
|
|
|
|
|
- return {id, name: 'John Doe'};
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// сервис, который зависит от двух других классов
|
|
|
|
|
-class UserService {
|
|
|
|
|
- constructor(db, logger) {
|
|
|
|
|
- if (!db || !logger) {
|
|
|
|
|
- throw new Error('Database and Logger are required!');
|
|
|
|
|
- }
|
|
|
|
|
- this.db = db;
|
|
|
|
|
- this.logger = logger;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- findUser(id) {
|
|
|
|
|
- this.logger.log(`Searching for user with id: ${id}`);
|
|
|
|
|
- return this.db.query(id);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// -- точка входа в приложение (или где-то в коде) ---
|
|
|
|
|
-
|
|
|
|
|
-// нужно вручную создать все зависимости
|
|
|
|
|
-const logger = new Logger();
|
|
|
|
|
-const dbClient = new DatabaseClient();
|
|
|
|
|
-
|
|
|
|
|
-// нужно вручную передать их в конструктор
|
|
|
|
|
-const userService = new UserService(dbClient, logger);
|
|
|
|
|
-
|
|
|
|
|
-userService.findUser(123);
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-Недостатки ручного управления зависимостями:
|
|
|
|
|
-
|
|
|
|
|
-- Жесткая связь и сложность.
|
|
|
|
|
- Точка входа в приложение превращается в "фабрику", которая знает,
|
|
|
|
|
- как создавать и связывать все компоненты. Если `DatabaseClient` тоже
|
|
|
|
|
- начнет зависеть от `Logger`, порядок создания усложнится.
|
|
|
|
|
-
|
|
|
|
|
-- Проблемы с тестированием.
|
|
|
|
|
- Чтобы протестировать `UserService` в изоляции, нужно создать "моки"
|
|
|
|
|
- для `Logger` и `DatabaseClient` и вручную передать их в конструктор.
|
|
|
|
|
- Это громоздко и требует дополнительного кода в каждом тесте.
|
|
|
|
|
-
|
|
|
|
|
-#### Решение: Инверсия управления
|
|
|
|
|
-
|
|
|
|
|
-Эта библиотека была создана для решения именно этих проблем. Она реализует
|
|
|
|
|
-принцип *инверсии управления (IoC)*, при котором контроль над созданием
|
|
|
|
|
-и предоставлением зависимостей передается от компонента к специализированному
|
|
|
|
|
-контейнеру.
|
|
|
|
|
-
|
|
|
|
|
-С библиотекой код становится проще:
|
|
|
|
|
-
|
|
|
|
|
-```js
|
|
|
|
|
-import {Service} from '@e22m4u/js-service';
|
|
|
|
|
-
|
|
|
|
|
-// зависимости (остаются простыми классами)
|
|
|
|
|
-class Logger {
|
|
|
|
|
- log(message) {
|
|
|
|
|
- console.log(message);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-class DatabaseClient {
|
|
|
|
|
- query(id) {
|
|
|
|
|
- return {id, name: 'John Doe'};
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// сервис наследует `Service` для доступа к `getService`
|
|
|
|
|
-class UserService extends Service {
|
|
|
|
|
- findUser(id) {
|
|
|
|
|
- // зависимости запрашиваются "по требованию" где они нужны,
|
|
|
|
|
- // контейнер сам позаботится об их создании и кешировании
|
|
|
|
|
- const logger = this.getService(Logger);
|
|
|
|
|
- const db = this.getService(DatabaseClient);
|
|
|
|
|
-
|
|
|
|
|
- logger.log(`Searching for user with id: ${id}`);
|
|
|
|
|
- return db.query(id);
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-// -- точка входа в приложение ---
|
|
|
|
|
-
|
|
|
|
|
-// мы просто создаем экземпляр нужного сервиса
|
|
|
|
|
-const userService = new UserService();
|
|
|
|
|
-userService.findUser(123);
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-Преимущества этого подхода:
|
|
|
|
|
-
|
|
|
|
|
-- Слабая связанность.
|
|
|
|
|
- `UserService` больше не знает, как создавать `Logger` или `DatabaseClient`.
|
|
|
|
|
- Он просто заявляет о своей потребности в них, вызывая `this.getService()`.
|
|
|
|
|
-
|
|
|
|
|
-- Простота и чистота кода.
|
|
|
|
|
- Точка входа в приложение становится тривиальной. Логика сборки зависимостей
|
|
|
|
|
- полностью инкапсулирована внутри контейнера, который неявно управляется
|
|
|
|
|
- базовым классом `Service`
|
|
|
|
|
-
|
|
|
|
|
-- Легкость тестирования.
|
|
|
|
|
- Подменить зависимость стало невероятно просто. Метод `setService` позволяет
|
|
|
|
|
- "на лету" подставить мок-объект.
|
|
|
|
|
-
|
|
|
|
|
-Пример подмены зависимости (mocking):
|
|
|
|
|
-
|
|
|
|
|
-```js
|
|
|
|
|
-// в файле теста
|
|
|
|
|
-const userService = new UserService();
|
|
|
|
|
-
|
|
|
|
|
-// создание мок-логгера
|
|
|
|
|
-const mockLogger = {log: () => {}}; // не будет писать в консоль
|
|
|
|
|
-
|
|
|
|
|
-// подмена реализации Logger в контейнере этого сервиса
|
|
|
|
|
-userService.setService(Logger, mockLogger);
|
|
|
|
|
-
|
|
|
|
|
-// теперь при вызове findUser будет использован наш мок-объект
|
|
|
|
|
-userService.findUser(456);
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
-Библиотека избавляет от рутины ручного управления зависимостями, делая
|
|
|
|
|
-архитектуру проекта гибкой, масштабируемой и легко тестируемой. Разработчик
|
|
|
|
|
-может сосредоточиться на бизнес-логике, а не на том, как и в каком порядке
|
|
|
|
|
-создавать и связывать объекты.
|
|
|
|
|
-
|
|
|
|
|
## Описание
|
|
## Описание
|
|
|
|
|
|
|
|
Модуль экспортирует два основных класса, `ServiceContainer` и `Service`,
|
|
Модуль экспортирует два основных класса, `ServiceContainer` и `Service`,
|
|
@@ -340,21 +188,12 @@ const myService = container.get(MyService);
|
|
|
- [`add(ctor, ...args)`](#servicecontaineradd) добавить конструктор в контейнер (ленивая инициализация);
|
|
- [`add(ctor, ...args)`](#servicecontaineradd) добавить конструктор в контейнер (ленивая инициализация);
|
|
|
- [`use(ctor, ...args)`](#servicecontaineruse) добавить конструктор и сразу создать экземпляр;
|
|
- [`use(ctor, ...args)`](#servicecontaineruse) добавить конструктор и сразу создать экземпляр;
|
|
|
- [`set(ctor, service)`](#servicecontainerset) добавить конструктор и связанный с ним готовый экземпляр;
|
|
- [`set(ctor, service)`](#servicecontainerset) добавить конструктор и связанный с ним готовый экземпляр;
|
|
|
-- [`find(predicate, noParent = false)`](#servicecontainerfind) найти сервис удовлетворяющий условию;
|
|
|
|
|
|
|
+- [`find(predicate, [noParent])`](#servicecontainerfind) найти сервис удовлетворяющий условию;
|
|
|
- [`getParent()`](#servicecontainergetparent-и-servicecontainerhasparent) получить родительский сервис-контейнер;
|
|
- [`getParent()`](#servicecontainergetparent-и-servicecontainerhasparent) получить родительский сервис-контейнер;
|
|
|
- [`hasParent()`](#servicecontainergetparent-и-servicecontainerhasparent) проверить наличие родительского сервис-контейнера;
|
|
- [`hasParent()`](#servicecontainergetparent-и-servicecontainerhasparent) проверить наличие родительского сервис-контейнера;
|
|
|
|
|
|
|
|
В сигнатурах методов используется вспомогательный тип конструктора:
|
|
В сигнатурах методов используется вспомогательный тип конструктора:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Конструктор класса.
|
|
|
|
|
- */
|
|
|
|
|
-interface Constructor<T extends object = object> {
|
|
|
|
|
- new (...args: any[]): T;
|
|
|
|
|
-}
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
### serviceContainer.get
|
|
### serviceContainer.get
|
|
|
|
|
|
|
|
Метод `get` класса `ServiceContainer` создает экземпляр
|
|
Метод `get` класса `ServiceContainer` создает экземпляр
|
|
@@ -363,15 +202,10 @@ interface Constructor<T extends object = object> {
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Получить существующий или новый экземпляр.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-get<T extends object>(ctor: Constructor<T>, ...args: any[]): T;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `get(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает новый или существующий экземпляр сервиса;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -411,16 +245,10 @@ console.log(myDate3); // Sun May 05 2030 03:00:00
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Получить существующий или новый экземпляр,
|
|
|
|
|
- * только если конструктор зарегистрирован.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-getRegistered<T extends object>(ctor: Constructor<T>, ...args: any[]): T;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `getRegistered(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает новый или существующий экземпляр сервиса;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -445,14 +273,9 @@ container.getRegistered(UnregisteredService);
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Проверить существование конструктора в контейнере.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- */
|
|
|
|
|
-has<T extends object>(ctor: Constructor<T>): boolean;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `has(ctor)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - возвращает `true` если класс зарегистрирован;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -474,15 +297,10 @@ console.log(container.has(MyService)); // true
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Добавить конструктор в контейнер.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-add<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `add(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает экземпляр сервис-контейнера;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -511,15 +329,10 @@ console.log('After get');
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Добавить конструктор и создать экземпляр.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-use<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `use(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает новый экземпляр сервиса;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -546,15 +359,10 @@ const service = container.get(MyService); // возвращает готовый
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Добавить конструктор и связанный экземпляр.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param service
|
|
|
|
|
- */
|
|
|
|
|
-set<T extends object>(ctor: Constructor<T>, service: T): this;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `set(ctor, service)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `service: object`: экземпляр сервиса;
|
|
|
|
|
+ - возвращает экземпляр сервис-контейнера;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -587,26 +395,10 @@ console.log(api === mock); // true
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Найти сервис удовлетворяющий условию.
|
|
|
|
|
- *
|
|
|
|
|
- * @param predicate
|
|
|
|
|
- * @param noParent
|
|
|
|
|
- */
|
|
|
|
|
-find<T extends object>(
|
|
|
|
|
- predicate: FindServicePredicate<T>,
|
|
|
|
|
- noParent?: boolean,
|
|
|
|
|
-): T | undefined;
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- * Определение функции-предиката.
|
|
|
|
|
- */
|
|
|
|
|
-type FindServicePredicate<T extends object> = (
|
|
|
|
|
- ctor: Constructor<T>,
|
|
|
|
|
- container: ServiceContainer,
|
|
|
|
|
-) => boolean;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `find(predicate, [noParent])`
|
|
|
|
|
+ - `predicate: Function`: функция-предикат для проверки конструктора;
|
|
|
|
|
+ - `noParent?: boolean`: отключить поиск в родительских контейнерах;
|
|
|
|
|
+ - возвращает найденный экземпляр или `undefined`;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -658,20 +450,6 @@ console.log(service2); // undefined
|
|
|
проверяет наличие родителя, а `getParent` возвращает его или выбрасывает
|
|
проверяет наличие родителя, а `getParent` возвращает его или выбрасывает
|
|
|
ошибку, если родителя нет.
|
|
ошибку, если родителя нет.
|
|
|
|
|
|
|
|
-Сигнатура:
|
|
|
|
|
-
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Получить родительский сервис-контейнер или выбросить ошибку.
|
|
|
|
|
- */
|
|
|
|
|
-getParent(): ServiceContainer;
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- * Проверить наличие родительского сервис-контейнера.
|
|
|
|
|
- */
|
|
|
|
|
-hasParent(): boolean;
|
|
|
|
|
-```
|
|
|
|
|
-
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
|
```js
|
|
```js
|
|
@@ -719,7 +497,7 @@ console.log(hasService); // true
|
|
|
- [`addService(ctor, ...args)`](#serviceaddservice) добавить конструктор в контейнер;
|
|
- [`addService(ctor, ...args)`](#serviceaddservice) добавить конструктор в контейнер;
|
|
|
- [`useService(ctor, ...args)`](#serviceuseservice) добавить конструктор и создать экземпляр;
|
|
- [`useService(ctor, ...args)`](#serviceuseservice) добавить конструктор и создать экземпляр;
|
|
|
- [`setService(ctor, service)`](#servicesetservice) добавить конструктор и его экземпляр;
|
|
- [`setService(ctor, service)`](#servicesetservice) добавить конструктор и его экземпляр;
|
|
|
-- [`findService(predicate, noParent = false)`](#servicefindservice) найти сервис удовлетворяющий условию;
|
|
|
|
|
|
|
+- [`findService(predicate, [noParent])`](#servicefindservice) найти сервис удовлетворяющий условию;
|
|
|
|
|
|
|
|
Сервисом может являться совершенно любой класс. Однако, если это
|
|
Сервисом может являться совершенно любой класс. Однако, если это
|
|
|
наследник класса `Service`, то такой сервис позволяет инкапсулировать
|
|
наследник класса `Service`, то такой сервис позволяет инкапсулировать
|
|
@@ -774,15 +552,10 @@ const app = new App();
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Получить существующий или новый экземпляр.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-getService<T extends object>(ctor: Constructor<T>, ...args: any[]): T;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `getService(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает новый или существующий экземпляр сервиса;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -804,19 +577,10 @@ console.log(foo3 === foo4); // true
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Получить существующий или новый экземпляр,
|
|
|
|
|
- * только если конструктор зарегистрирован.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-getRegisteredService<T extends object>(
|
|
|
|
|
- ctor: Constructor<T>,
|
|
|
|
|
- ...args: any[],
|
|
|
|
|
-): T;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `getRegisteredService(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает новый или существующий экземпляр сервиса;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -844,14 +608,9 @@ class MyService extends Service {
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Проверка существования конструктора в контейнере.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- */
|
|
|
|
|
-hasService<T extends object>(ctor: Constructor<T>): boolean;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `hasService(ctor)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - возвращает `true` если класс зарегистрирован;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -876,15 +635,10 @@ class MyService extends Service {
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Добавить конструктор в контейнер.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-addService<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `addService(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает экземпляр сервис-контейнера;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -908,15 +662,10 @@ class App extends Service {
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Добавить конструктор и создать экземпляр.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param args
|
|
|
|
|
- */
|
|
|
|
|
-useService<T extends object>(ctor: Constructor<T>, ...args: any[]): this;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `useService(ctor, ...args)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `...args: *[]`: аргументы конструктора;
|
|
|
|
|
+ - возвращает новый экземпляр сервиса;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -943,15 +692,10 @@ class App extends Service {
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Добавить конструктор и связанный экземпляр.
|
|
|
|
|
- *
|
|
|
|
|
- * @param ctor
|
|
|
|
|
- * @param service
|
|
|
|
|
- */
|
|
|
|
|
-setService<T extends object>(ctor: Constructor<T>, service: T): this;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `setService(ctor, service)`
|
|
|
|
|
+ - `ctor: Function`: класс сервиса;
|
|
|
|
|
+ - `service: object`: экземпляр сервиса;
|
|
|
|
|
+ - возвращает экземпляр сервис-контейнера;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|
|
@@ -980,26 +724,10 @@ class MyComponent extends Service {
|
|
|
|
|
|
|
|
Сигнатура:
|
|
Сигнатура:
|
|
|
|
|
|
|
|
-```ts
|
|
|
|
|
-/**
|
|
|
|
|
- * Найти сервис удовлетворяющий условию.
|
|
|
|
|
- *
|
|
|
|
|
- * @param predicate
|
|
|
|
|
- * @param noParent
|
|
|
|
|
- */
|
|
|
|
|
-findService<T extends object>(
|
|
|
|
|
- predicate: FindServicePredicate<T>,
|
|
|
|
|
- noParent?: boolean,
|
|
|
|
|
-): T | undefined;
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- * Определение функции-предиката.
|
|
|
|
|
- */
|
|
|
|
|
-type FindServicePredicate<T extends object> = (
|
|
|
|
|
- ctor: Constructor<T>,
|
|
|
|
|
- container: ServiceContainer,
|
|
|
|
|
-) => boolean;
|
|
|
|
|
-```
|
|
|
|
|
|
|
+- `findService(predicate, [noParent])`
|
|
|
|
|
+ - `predicate: Function`: функция-предикат для проверки конструктора;
|
|
|
|
|
+ - `noParent?: boolean`: отключить поиск в родительских контейнерах;
|
|
|
|
|
+ - возвращает найденный экземпляр или `undefined`;
|
|
|
|
|
|
|
|
Пример:
|
|
Пример:
|
|
|
|
|
|