Реализация принципа инверсии управления для JavaScript

e22m4u 38c8bc77bf chore: updates README.md 2 лет назад
.husky 899e75e1f5 chore: initial commit 2 лет назад
src 32404d6188 chore: adds "use" method to the ServiceContainer and "useService" to the Service class 2 лет назад
.c8rc 899e75e1f5 chore: initial commit 2 лет назад
.commitlintrc 899e75e1f5 chore: initial commit 2 лет назад
.editorconfig 899e75e1f5 chore: initial commit 2 лет назад
.eslintrc.cjs 899e75e1f5 chore: initial commit 2 лет назад
.gitignore 899e75e1f5 chore: initial commit 2 лет назад
.mocharc.cjs 899e75e1f5 chore: initial commit 2 лет назад
.prettierrc 899e75e1f5 chore: initial commit 2 лет назад
LICENSE 899e75e1f5 chore: initial commit 2 лет назад
README.md 38c8bc77bf chore: updates README.md 2 лет назад
mocha.setup.js 899e75e1f5 chore: initial commit 2 лет назад
package.json 2e9b48e163 chore: bumps version to 0.0.3 2 лет назад

README.md

@e22m4u/service

Разновидность сервис-локатора для инкапсуляции процесса разрешения зависимостей.

Установка

npm install @e22m4u/service

ServiceContainer

Методы:

  • get(ctor, ...args) получить существующий или новый экземпляр
  • has(ctor) проверка существования конструктора в контейнере
  • add(ctor, ...args) добавить конструктор в контейнер
  • use(ctor, ...args) добавить конструктор и создать экземпляр

get

Метод get класса ServiceContainer инкапсулирует создание экземпляра полученного конструктора и сохраняет его для последующих обращений по принципу "одиночки".

Пример:

import {ServiceContainer} from '@e22m4u/service';

// создание контейнера
const container = new ServiceContainer();

// в качестве сервиса используем класс Date
const myDate1 = container.get(Date); // создание экземпляра
const myDate2 = container.get(Date); // возврат существующего

console.log(myDate1); // Tue Sep 12 2023 19:50:16
console.log(myDate2); // Tue Sep 12 2023 19:50:16
console.log(myDate1 === myDate2); // true

Метод get может принимать аргументы конструктора. При этом, если контейнер уже имеет экземпляр данного конструктора, то он будет пересоздан с новыми аргументами.

Пример:

const myDate1 = container.get(Date, '2025-01-01'); // создание экземпляра
const myDate2 = container.get(Date);               // возврат существующего
const myDate3 = container.get(Date, '2025-05-05'); // пересоздание
console.log(myDate1); // Wed Jan 01 2025 03:00:00
console.log(myDate2); // Wed Jan 01 2025 03:00:00
console.log(myDate3); // Sun May 05 2030 03:00:00

Service

Методы:

  • getService(ctor, ...args) получить существующий или новый экземпляр
  • hasService(ctor) проверка существования конструктора в контейнере
  • addService(ctor, ...args) добавить конструктор в контейнер
  • useService(ctor, ...args) добавить конструктор и создать экземпляр

Сервисом может являться совершенно любой класс. Однако, если это наследник встроенного класса Service, то такой сервис позволяет инкапсулировать создание сервис-контейнера, его хранение и передачу другим сервисам.

Пример:

import {Service} from '@e22m4u/service';

// сервис Foo
class Foo extends Service {
  method() {
    // доступ к сервису Bar
    const bar = this.getService(Bar);
    // ...
  }
}

// сервис Bar
class Bar extends Service {
  method() {
    // доступ к сервису Foo
    const foo = this.getService(Foo);
    // ...
  }
}

// сервис App (точка входа)
class App extends Service {
  method() {
    // доступ к сервисам Foo и Bar
    const foo = this.getService(Foo);
    const bar = this.getService(Bar);
    // ...
  }
}

const app = new App();

В примере выше мы не заботились о создании сервис-контейнера и его передачу между сервисами, так как эта логика инкапсулирована в классе Service и его методе getService

getService

Метод getService обеспечивает существование единственного экземпляра запрашиваемого сервиса, а не создает каждый раз новый. Тем не менее при передаче дополнительных аргументов, сервис будет пересоздан с передачей этих аргументов конструктору.

Пример:

const foo1 = this.getService(Foo, 'arg'); // создание экземпляра
const foo2 = this.getService(Foo);        // возврат существующего
console.log(foo1 === foo2);               // true

const foo3 = this.getService(Foo, 'arg'); // пересоздание экземпляра
const foo4 = this.getService(Foo);        // возврат уже пересозданного
console.log(foo3 === foo4);               // true

Тесты

npm run test

Лицензия

MIT