Skip to content

Commit

Permalink
Support passing AwilixContainer explicitly (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
kibertoad authored Feb 7, 2024
1 parent bef3617 commit 044f0e3
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 155 deletions.
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![NPM Version][npm-image]][npm-url]
[![Build Status](https://github.com/fastify/fastify-awilix/workflows/ci/badge.svg)](https://github.com/fastify/fastify-awilix/actions)

Dependency injection support for fastify framework, using [awilix](https://github.com/jeffijoe/awilix)
Dependency injection support for fastify framework, using [awilix](https://github.com/jeffijoe/awilix).

## Getting started

Expand All @@ -26,7 +26,11 @@ app.register(fastifyAwilixPlugin, { disposeOnClose: true, disposeOnResponse: tru
Then, register some modules for injection:

```js
const { diContainer } = require('@fastify/awilix')
const {
diContainer, // this is an alias for diContainerProxy
diContainerClassic, // this instance will be used for `injectionMode = 'CLASSIC'`
diContainerProxy // this instance will be used by default
} = require('@fastify/awilix')
const { asClass, asFunction, Lifetime } = require('awilix')

// Code from the previous example goes here
Expand Down Expand Up @@ -74,6 +78,10 @@ app.post('/', async (req, res) => {

## Plugin options

`injectionMode` - whether to use PROXY or CLASSIC injection mode. See [awilix documentation](https://www.npmjs.com/package/awilix#injection-modes) for details. Default is 'PROXY'.

`container` - pre-created AwilixContainer instance that should be used by the plugin. By default plugin uses its own instance. Note that you can't specify both `injectionMode` and `container` parameters at the same time.

`disposeOnClose` - automatically invoke configured `dispose` for app-level `diContainer` hooks when the fastify instance is closed.
Disposal is triggered within `onClose` fastify hook.
Default value is `true`
Expand Down Expand Up @@ -178,18 +186,6 @@ await app.register(fastifyAwilixPlugin, { asyncInit: true, asyncDispose: true, e
await app.ready()
```

## Using classic injection mode

If you prefer [classic injection](https://github.com/jeffijoe/awilix#injection-modes), you can use it like this:

```javascript
const { fastifyAwilixPlugin } = require('@fastify/awilix/lib/classic')
const fastify = require('fastify')

app = fastify({ logger: true })
app.register(fastifyAwilixPlugin, { disposeOnClose: true, disposeOnResponse: true })
```

## Advanced DI configuration

For more advanced use-cases, check the official [awilix documentation](https://github.com/jeffijoe/awilix)
Expand Down
1 change: 0 additions & 1 deletion lib/classic/index.d.ts

This file was deleted.

70 changes: 0 additions & 70 deletions lib/classic/index.js

This file was deleted.

30 changes: 25 additions & 5 deletions lib/fastifyAwilixPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,31 @@ const awilix = require('awilix')
const { AwilixManager } = require('awilix-manager')
const fp = require('fastify-plugin')

const diContainer = awilix.createContainer({
const diContainerProxy = awilix.createContainer({
injectionMode: 'PROXY',
})

const diContainerClassic = awilix.createContainer({
injectionMode: 'CLASSIC',
})

function plugin(fastify, opts, next) {
if (opts.container && opts.injectionMode) {
return next(
new Error(
'If you are passing pre-created container explicitly, you cannot specify injection mode',
),
)
}

const resolvedContainer = opts.container
? opts.container
: opts.injectionMode === 'CLASSIC'
? diContainerClassic
: diContainerProxy

const awilixManager = new AwilixManager({
diContainer,
diContainer: resolvedContainer,
asyncDispose: opts.asyncDispose,
asyncInit: opts.asyncInit,
eagerInject: opts.eagerInject,
Expand All @@ -19,11 +37,11 @@ function plugin(fastify, opts, next) {
const disposeOnClose = opts.disposeOnClose === true || opts.disposeOnClose === undefined

fastify.decorate('awilixManager', awilixManager)
fastify.decorate('diContainer', diContainer)
fastify.decorate('diContainer', resolvedContainer)
fastify.decorateRequest('diScope', null)

fastify.addHook('onRequest', (request, reply, done) => {
request.diScope = diContainer.createScope()
request.diScope = resolvedContainer.createScope()
done()
})

Expand Down Expand Up @@ -65,6 +83,8 @@ const fastifyAwilixPlugin = fp(plugin, {
})

module.exports = {
diContainer,
diContainer: diContainerProxy,
diContainerProxy,
diContainerClassic,
fastifyAwilixPlugin,
}
4 changes: 4 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ declare module 'fastify' {
export type FastifyAwilixOptions = {
disposeOnResponse?: boolean
disposeOnClose?: boolean
injectionMode?: 'PROXY' | 'CLASSIC'
container?: AwilixContainer<Cradle>
asyncInit?: boolean
asyncDispose?: boolean
eagerInject?: boolean
Expand All @@ -28,3 +30,5 @@ export type FastifyAwilixOptions = {
export const fastifyAwilixPlugin: FastifyPluginCallback<NonNullable<FastifyAwilixOptions>>

export const diContainer: AwilixContainer<Cradle>
export const diContainerClassic: AwilixContainer<Cradle>
export const diContainerProxy: AwilixContainer<Cradle>
9 changes: 8 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
'use strict'

const { diContainer, fastifyAwilixPlugin } = require('./fastifyAwilixPlugin')
const {
diContainer,
fastifyAwilixPlugin,
diContainerProxy,
diContainerClassic,
} = require('./fastifyAwilixPlugin')

module.exports = {
diContainer,
diContainerClassic,
diContainerProxy,
fastifyAwilixPlugin,
}
8 changes: 6 additions & 2 deletions lib/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { asValue, AwilixContainer } from 'awilix'
import fastify, { FastifyInstance } from 'fastify'
import { diContainer, FastifyAwilixOptions, fastifyAwilixPlugin, Cradle, RequestCradle } from './index'
import { diContainer as diContainerClassic } from './classic'
import { diContainer, diContainerClassic, FastifyAwilixOptions, fastifyAwilixPlugin, Cradle, RequestCradle } from './index'

import { expectAssignable, expectNotType, expectType } from 'tsd'

expectAssignable<FastifyAwilixOptions>({})
expectAssignable<FastifyAwilixOptions>({ disposeOnClose: false })
expectAssignable<FastifyAwilixOptions>({ container: diContainer })
expectAssignable<FastifyAwilixOptions>({ container: diContainerClassic })
expectAssignable<FastifyAwilixOptions>({ injectionMode: 'CLASSIC' })
expectAssignable<FastifyAwilixOptions>({ injectionMode: 'PROXY' })

expectAssignable<FastifyAwilixOptions>({ disposeOnResponse: false })
expectAssignable<FastifyAwilixOptions>({ asyncInit: false, asyncDispose: false })
expectAssignable<FastifyAwilixOptions>({ asyncInit: true, asyncDispose: true })
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
"@types/node": "^20.8.6",
"awilix": "^10.0.1",
"eslint": "^8.51.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"fastify": "^4.24.2",
"jest": "^29.7.0",
"prettier": "^3.0.3",
"prettier": "^3.2.5",
"tsd": "^0.30.0"
},
"homepage": "http://github.com/fastify/fastify-awilix",
Expand Down
36 changes: 19 additions & 17 deletions test/awilixManager.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@

const { asClass } = require('awilix')
const fastify = require('fastify')
const { diContainer, fastifyAwilixPlugin } = require('../lib')

const {
diContainer: diContainerClassic,
fastifyAwilixPlugin: fastifyAwilixPluginClassic,
} = require('../lib/classic')
const { diContainer, diContainerClassic, fastifyAwilixPlugin } = require('../lib')

let isInittedGlobal = false
let isDisposedGlobal = false
Expand All @@ -32,20 +27,18 @@ class AsyncInitSetClass {

const variations = [
{
name: 'PROXY',
plugin: fastifyAwilixPlugin,
injectionMode: 'PROXY',
container: diContainer,
},
{
name: 'CLASSIC',
plugin: fastifyAwilixPluginClassic,
injectionMode: 'CLASSIC',
container: diContainerClassic,
},
]

describe('awilixManager', () => {
variations.forEach((variation) => {
describe(variation.name, () => {
describe(variation.injectionMode, () => {
let app
beforeEach(() => {
isInittedGlobal = false
Expand All @@ -66,10 +59,13 @@ describe('awilixManager', () => {
asClass(InitSetClass, {
lifetime: 'SINGLETON',
eagerInject: true,
})
}),
)
app = fastify({ logger: false })
await app.register(variation.plugin, { eagerInject: true })
await app.register(fastifyAwilixPlugin, {
eagerInject: true,
injectionMode: variation.injectionMode,
})
await app.ready()

expect(isInittedGlobal).toBe(true)
Expand All @@ -81,10 +77,13 @@ describe('awilixManager', () => {
asClass(AsyncInitSetClass, {
lifetime: 'SINGLETON',
asyncInit: 'init',
})
}),
)
app = fastify({ logger: false })
await app.register(variation.plugin, { asyncInit: true })
await app.register(fastifyAwilixPlugin, {
asyncInit: true,
injectionMode: variation.injectionMode,
})
await app.ready()

expect(isInittedGlobal).toBe(true)
Expand All @@ -96,10 +95,13 @@ describe('awilixManager', () => {
asClass(AsyncInitSetClass, {
lifetime: 'SINGLETON',
asyncDispose: 'dispose',
})
}),
)
app = fastify({ logger: false })
await app.register(variation.plugin, { asyncDispose: true })
await app.register(fastifyAwilixPlugin, {
asyncDispose: true,
injectionMode: variation.injectionMode,
})
await app.ready()
await app.close()

Expand Down
Loading

0 comments on commit 044f0e3

Please sign in to comment.