🦄 2024 独立开发者训练营,一起创业!(早鸟优惠在6天后结束)查看介绍 / 立即报名 →

Node.js:Adonis 框架 Service Providers

前面我们了解过怎么把依赖绑定到 IoC 容器里,下面继续往后看看关于 Service Providers 的东西,了解怎么发行与 Adonis 生态系统相兼容的包。

介绍

ioc.bind 方法可以用来注册绑定,不过现在还没有明确的说明要在哪里调用这个方法。这就是 Service Providers 做的事情。Service Providers 就是简单的类,里面带着一些生命周期方法可以用来注册与启动绑定。

const { ServiceProvider } = require('@adonisjs/fold')

class MyProvider extends ServiceProvider {
  register () {
    // register bindings
  }

  boot () {
    // optionally do some initial setup
  }
}

module.exports = MyProvider

Provider 类里的 register 方法是用来注册绑定的,在这个方法里你不能使用其它的绑定。boot 方法会在所有的 providers 都已经注册了以后被调用。这时候可以使用已有的绑定去做一些初始化的操作。

比如,添加一个 View global:

boot () {
  const View = this.app.use('Adonis/Src/View')
  View.global('time', () => new Date().getTime())
}

Npm 包作为 Service Provider

下面了解一下怎么把已有的 npm 包变成一个 Service Provider。应用里的 Provider 存储在应用根目录下的 providers 这个目录里面。

目录结构

├── app
└── providers
  └── Queue
    └── index.js
    └── Provider.js
└── start

原则

比如我们要把 bee-queue 注册成一个 Provider。下面是一些遵循的原则。

  1. 用户不需要配置 queue provider。
  2. 所有的配置放在 config/queue.js 文件里。
  3. 使用不同配置创建新的 queue 要非常简单。

实施

providers/Queue/index.js:

'use strict'

const BeeQueue = require('bee-queue')

class Queue {
  constructor (Config) {
    this.Config = Config
    this._queuePool = {}
  }

  get (name) {
    /**
     * If there is an instance of queue already, then return it
     */
    if (this._queuesPool[name]) {
      return this._queuesPool[name]
    }

    /**
     * Read configuration using Config
     * provider
     */
    const config = this.Config.get(`queue.${name}`)

    /**
     * Create a new queue instance and save it's
     * reference
     */
    this._queuesPool[name] = new BeeQueue(name, config)

    /**
     * Return the instance back
     */
    return this._queuesPool[name]
  }
}

module.exports = Queue

上面这类里面只有一个 get 方法,它会返回指定名字的 queue 实例。下面是 get 方法做的事情:

  1. 查找指定名字的 queue 实例。
  2. 如果实例不存在,在 Config provider 那里读取相关配置。
  3. 创建新的 bee-queue 实例存储在一个对象里。
  4. 返回实例。

Queue 保持了纯洁性,因为它不强依赖框架里的东西,它需要的 Config ,会用依赖注入(Dependency Injection)的方式提供。

Service provider

现在可以去创建一个 Service provider,用它实例化上面的类并且把它绑定在 Ioc 容器里。下面代码在 providers/Queue/Provider.js 文件里:

const { ServiceProvider } = require('@adonisjs/fold')

class QueueProvider extends ServiceProvider {
  register () {
    this.app.singleton('Bee/Queue', () => {
       const Config = this.app.use('Adonis/Src/Config')
       return new (require('.'))(Config)
    })
  }
}

module.exports = QueueProvider

this.app 指的就是 ioc 对象,所以我们可以使用 this.app.singleton 代替 ioc.singleton 。

最后,我们需要在 start/app.js 文件里注册 Provider :

const providers = [
  path.json(__dirname, '..', 'providers', 'Queue/provider')
]

现在,我们就可以在应用的任何文件里使用 use('Bee/Queue') :

const Queue = use('Bee/Queue')

Queue
  .get('addition')
  .createJob({ x:2, y:3 })
  .save()

发行包

把之前创建的 bee queue provider 做成自己的包。创建一个目录结构:

└── providers
    └── QueueProvider.js
├── src
  └── Queue
    └── index.js
└── package.json

主要就是把实施的 Queue 放在了 src 目录的下面,名字改成了 QueueProvider.js 。

另外还需要做下面这些修改:

  1. 因为 Queue/index.js 在不同的目录里了,所以得在 Service provider 里面修改这个文件的引用。
  2. 重命名 Bee/Queue,比如 Adonis/Addons/Queue。
const { ServiceProvider } = require('@adonisjs/fold')

class QueueProvider extends ServiceProvider {
  register () {
    this.app.singleton('Adonis/Addons/Queue', () => {
      const Config = this.app.use('Adonis/Src/Config')
      return new (require('../src/Queue'))(Config)
    })
  }
}

module.exports = QueueProvider
Node.js

评论

这个博客的质量真的太高了,宁皓网就是个宝藏

谢谢啊。嘿嘿。

微信好友

用微信扫描二维码,
加我好友。

微信公众号

用微信扫描二维码,
订阅宁皓网公众号。

240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

14696
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点