Начиная с выпуска v1 в начале 2017 года, ядро ​​фреймворка FrintJS в основном отвечает за обработку зависимостей в ваших приложениях. В то время как другие пакеты в основном построены на основе API ядра frint пакета.

Провайдеры

У нас есть терминология для обозначения зависимостей в ваших приложениях FrintJS. Мы называем их провайдерами. Провайдеры - это любое значение, которое вы можете определить в своем приложении FrintJS, которое позже может быть получено по их уникальным именам.

Создать приложение FrintJS очень просто:

import { createApp } from 'frint';
const MyApp = createApp({
  name: 'MyAppName',
});

Ниже мы покажем вам, как провайдеры могут быть определены в вашем приложении тремя различными способами.

(Вы найдете некоторое сходство с Angular 2+, потому что frint использует форк diyai, который является портом Angular's Injector API, созданным таким образом, чтобы его можно было использовать без TypeScript)

Известные ценности

Если вы уже знаете значение своего провайдера, вы можете использовать свойство useValue следующим образом:

import { createApp } from 'frint';
const MyApp = createApp({
  name: 'MyAppName',
  providers: [
    {
      name: 'foo',
      useValue: 'foo value here',
    },
  ],
});

Теперь, когда вы создали экземпляр своего приложения, вы можете получить значение foo следующим образом:

const app = new MyApp();
const foo = app.get('foo'); // `foo value here`

Сгенерированные значения

Бывают случаи, когда вы на самом деле не знаете ценности своего провайдера и можете сгенерировать их только при создании экземпляра самого приложения. Свойство useFactory можно использовать в этих сценариях:

import { createApp } from 'frint';
const MyApp = createApp({
  name: 'MyAppName',
  providers: [
    {
      name: 'bar',
      useFactory: function () {
        return 'bar value here';
      },
    },
  ],
});

Теперь поставщик bar можно получить из экземпляра вашего приложения следующим образом:

const app = new MyApp();
const bar = app.get('bar'); // `bar value here`

Обратите внимание, что функция, генерирующая значение bar, вызывается только один раз во время создания экземпляра приложения. После этого он будет продолжать возвращать одно и то же кешированное значение из внутреннего реестра приложения всех поставщиков.

Генерируется из классов ES6

Также есть случаи, когда вы также можете сначала написать своих провайдеров как классы ES6:

class Baz {
  getValue() {
    return 'baz value here';
  }
}

Чтобы установить классы ES6 в качестве поставщиков, мы можем использовать свойство useClass при их определении в приложениях FrintJS:

import { createApp } from 'frint';
const MyApp = createApp({
  name: 'MyAppName',
  providers: [
    {
      name: 'baz',
      useClass: Baz,
    },
  ],
});

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

const app = new MyApp();
const baz = app.get('baz'); // instance of Baz class
console.log(baz.getValue()); // `baz value here`

Подобно useFactory, класс будет создан только один раз во время создания вашего приложения и будет возвращать одно и то же кэшированное значение каждый раз, когда вы делаете app.get('baz').

Инъекционные провайдеры в других провайдерах

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

Из приведенных выше примеров предположим, что bar провайдер должен знать значение foo. Как нам ввести foo в bar?

Мы можем использовать свойство deps (сокращение от dependencies):

import { createApp } from 'frint';
const MyApp = createApp({
  name: 'MyAppName',
  providers: [
    {
      name: 'foo',
      useValue: 'foo value here',
    },
    {
      name: 'bar',
      useFactory: function (deps) {
        const { foo } = deps; // `foo value here`
        return foo + ', bar value here';
      },
      deps: ['foo'],
    },
  ],
});

Вот что мы только что сделали выше:

  • Определить foo провайдера
  • Определить bar провайдера
  • Для bar укажите foo как зависимость
  • Функция, генерирующая значение bar, теперь получит объект deps со всеми его зависимостями, привязанными к их именам. Поскольку мы указали только foo в качестве зависимости, на данный момент она получит foo только.
  • Сгенерированное значение bar теперь возвращает foo value here, baz value here.

Вы можете попробовать сами:

const app = new MyApp();
const foo = app.get('foo');
const bar = app.get('bar');
console.log(bar); // `foo value here, bar value here`

Вы можете применить аналогичную технику и для useClass. Затем объект deps будет передан классу в качестве его первого аргумента конструктора:

class Baz {
  constructor(deps) {
    console.log(deps);
  }
}

Вы можете прочитать об этом подробнее в официальной документации для пакета frint здесь: https://frint.js.org/docs/packages/frint/.