Следуя соглашению NestJS о внедрении зависимостей со сторонними библиотеками
NestJS использует принцип DI (внедрение зависимостей) и IoC (инверсия управления), где классу предоставляется объект (от которого он зависит, он же «зависимость ») в качестве аргумента его конструктору. Кроме того, работа по созданию и внедрению этих зависимостей делегируется фреймворку с использованием декораторов, которые помещают соответствующие метаданные в классы, которые будут использоваться фреймворком для разрешения зависимостей.
Но время от времени мы сталкиваемся с библиотеками, которые экспортируют классы, экземпляры которых не могут быть созданы фреймворком. Например, Pusher — это сервис, который можно использовать для создания приложения для общения в реальном времени. Он поставляется с библиотекой Node.js pusher
, которая экспортирует класс Pusher
Чтобы работать с библиотекой, нам сначала нужно создать ее экземпляр, используя учетные данные, которые мы получили, создав приложение в консоли pusher. Вот как вы могли бы создать экземпляр в Node.js, используя TypeScript
Но если вы использовали NestJS, вы бы знали, что в NestJS все делается иначе. Мы могли бы попробовать внедрить класс Pusher
в такой сервис.
Но это не удастся по двум причинам
- У класса нет необходимых метаданных
- Требуется создание экземпляра объекта options
Вместо этого мы можем использовать Динамические модули и Пользовательские поставщики, чтобы сделать его инжектируемым.
Начнем с создания динамического модуля.
В этом модуле статический метод forRoot
принимает объект параметров, который имеет тип объекта параметров, требуемый классом Pusher
.
Затем в массиве поставщиков определяется пользовательский поставщик токена, не основанный на классе. По сути, это говорит о том, что если мы введем токен PUSHER_CONFIG_OPTIONS
с помощью декоратора @Inject()
внутри любой службы в этом модуле, он предоставит объект параметров
Теперь мы определяем наш класс PusherInjectable
, как показано ниже.
Класс PusherInjectable
сначала расширяет класс Pusher
, экспортированный из пакета pusher
. Поскольку базовому классу требуется объект параметров, он передается ему в вызове super()
. Этот объект опций вводится с использованием токена, определенного выше в динамическом модуле. Обратите внимание, что этот класс украшен декоратором @Injectable()
, который позволяет Nest разрешать зависимости этого класса. Последнее, что нужно сделать, это зарегистрировать этот класс в списке провайдеров содержащего его модуля.
Этот динамический модуль экспортирует службу PusherInjectable
, и модуль также украшен декоратором @Global()
, что означает, что нам нужно импортировать PusherModule
только один раз в AppModule
, а затем класс PusherInjectable
можно внедрить как зависимость в любом месте приложения.
Вот как PusherModule
импортируется в AppModule
Ссылка на репозиторий GitHub — https://github.com/Aekant/pusher-nestjs.