nestjs-multi-provider
v0.3.2
Published
This package patches NestJS with the multi provider pattern.
Downloads
155
Maintainers
Readme
NestJS patch for multi provider pattern
This package patches the Nest.js Module
decorator so that you can
somewhat straightforwardly use the multi-provider pattern. This package lets you specify
the multi
flag to providers. You can then collect these providers into an array using
the collect
function in the imports
attribute of a target module, and inject the
collected array of provided values anywhere in the target module.
Installation
npm install nestjs-multi-provider
Usage
A full example is available here.
On the first line of your root module file (most likely src/app.module.ts
), import the
package to activate the patch:
import 'nestjs-multi-provider';
Note: This package monkey-patches the Module
decorator, if for some reason you
can't, see the failsafe method.
1. Provide
Simply use any of the provider patterns NestJS supports, and add the multi
property. You
can do this from any module, any amount of times. All the providers will ultimately be
available under the same token as an array of provided values.
@Module({
providers: [
{provide: SOME_TOKEN, useClass: SomeService, multi: true},
{provide: SOME_TOKEN, useClass: SomeServiceWithDeps, multi: true, standalone: false},
]
})
Important: If your provider has dependencies, you must set standalone
to false
.
2. Collect
To access all your providers, use the collect
function:
@Module({
imports: [collect(SOME_TOKEN)]
})
export class CollectingModule {}
3. Inject
You can now inject your array of providers anywhere inside of CollectingModule
:
export class SomeServiceInCollectingModule {
constructor(@Inject(SOME_TOKEN) collection: any[]) {
console.log("Collected:", collection)
// This will print `Collected: [SomeService {}, SomeServiceWithDeps {}]`
}
}
Using the failsafe decorator
Instead of using the patched Module
decorator, you can also decorate any modules that
provide multi-providers with the ModuleWithMulti
decorator:
import { ModuleWithMulti } from "nestjs-multi-provider";
@ModuleWithMulti({
providers: [{provide: "something", useValue: 1, multi: true}]
})
export class MyModule {}
During testing
I have noticed during testing that the monkey patch doesn't always function because certain statements may be hoisted above the patch. You can overcome this by creating a statement that itself will be hoisted. For example, for Jest:
import { ModuleWithMulti } from "nestjs-multi-provider";
jest.mock('@nestjs/common', () => {
const nestjsCommon = jest.requireActual('@nestjs/common');
return {
...nestjsCommon,
Module: ModuleWithMulti,
};
});
Important notes
- Your providers are not available unless you use
collect
. collect
creates aDynamicModule
and therefor must be placed in theimports
property.- Your providers are by default considered
standalone
(not having any dependencies), and are not actually provided by the module they are declared in, but by the collectingDynamicModule
. This is done to avoid creating needless dependencies between modules. - If your provider has dependencies, set
standalone
tofalse
to have access to the declaring module's providers. Doing this will result in aforwardRef
of the declaring module by the collecting module. - Multi providers are not supported in
DynamicModule
s.