前面我们了解过怎么把依赖绑定到 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 = MyProviderProvider 类里的 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。下面是一些遵循的原则。
- 用户不需要配置 queue provider。
- 所有的配置放在 config/queue.js 文件里。
- 使用不同配置创建新的 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 方法做的事情:
- 查找指定名字的 queue 实例。
- 如果实例不存在,在 Config provider 那里读取相关配置。
- 创建新的 bee-queue 实例存储在一个对象里。
- 返回实例。
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 = QueueProviderthis.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 。
另外还需要做下面这些修改:
- 因为 Queue/index.js 在不同的目录里了,所以得在 Service provider 里面修改这个文件的引用。
- 重命名 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 



评论
这个博客的质量真的太高了,宁皓网就是个宝藏
7 年 8 个月 以前
谢谢啊。嘿嘿。
7 年 8 个月 以前