fix(di): decorate injectable constructor params with explicit @Inject - #24
Merged
Conversation
The package ships a tsup/esbuild bundle, and esbuild does not emit
`emitDecoratorMetadata` (design:paramtypes). Providers whose constructor
params were resolved purely by reflected type metadata (QueueService,
WorkerRegistry, QueueEventsRegistry, ProcessorDiscoveryService, QueueLifecycle)
therefore could not be instantiated by a consumer's Nest DI container from the
built dist ("Nest can't resolve dependencies ... argument at index [0]").
Decorate every such parameter with an explicit @Inject(Token). This makes DI
independent of reflected metadata (aligning with the explicit-DI standard and
matching @bymax-one/nest-cache), so the module boots from the bundled dist.
Factory-provided services (FlowService, MetricsService, ConnectionResolver) are
unaffected — their args are supplied by their useFactory inject arrays.
There was a problem hiding this comment.
Pull request overview
This PR makes NestJS DI work when consuming the bundled dist output (tsup/esbuild) by removing reliance on emitDecoratorMetadata (design:paramtypes) and switching constructor dependency resolution to explicit @Inject(...) tokens for the directly-instantiated class providers.
Changes:
- Added explicit
@Inject(ClassToken)decorations to constructor parameters in the module’s class providers so DI no longer depends on reflected param types. - Updated relevant imports to include
Injectwhere needed.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/server/services/worker-registry.service.ts | Adds explicit @Inject(ConnectionResolver) for the ConnectionResolver constructor dependency. |
| src/server/services/queue.service.ts | Adds explicit @Inject(ConnectionResolver) so QueueService can be instantiated from bundled dist. |
| src/server/services/queue-events-registry.service.ts | Imports Inject and explicitly injects ConnectionResolver in the constructor. |
| src/server/services/processor-discovery.service.ts | Imports Inject and explicitly injects DiscoveryService, WorkerRegistry, and QueueEventsRegistry. |
| src/server/lifecycle/queue-lifecycle.service.ts | Explicitly injects all constructor dependencies (WorkerRegistry, QueueEventsRegistry, QueueService, FlowService, ConnectionResolver). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The package ships a tsup/esbuild bundle. esbuild does not emit
emitDecoratorMetadata(design:paramtypes= 0 in the builtdist), so providers whose constructor parameters were resolved purely by reflected type metadata could not be instantiated by a consumer's NestJS DI container from the built dist:This blocked every consumer of the built package (surfaced while wiring
nest-queue-example).Fix
Decorate every reflection-resolved constructor parameter with an explicit
@Inject(Token)in the five class providers that Nest instantiates directly:QueueService,WorkerRegistry,QueueEventsRegistry,ProcessorDiscoveryService,QueueLifecycle. This makes DI independent of reflected metadata — aligning with the explicit-DI standard and matching@bymax-one/nest-cache— so the module boots from the bundled dist.Factory-provided services (
FlowService,MetricsService,ConnectionResolver) are unaffected: their arguments are supplied by theiruseFactoryinjectarrays.Verification
pnpm build(tsup) OK;pnpm typecheckOK;pnpm lintOK.dist:Test.createTestingModule({ imports: [BymaxQueueModule.forRoot({ connection: { url } })] }).compile()now resolvesQueueService(previously threw the dependency-resolution error).