Skip to content

fix(di): decorate injectable constructor params with explicit @Inject - #24

Merged
msalvatti merged 1 commit into
mainfrom
fix/explicit-di-inject
Jul 9, 2026
Merged

fix(di): decorate injectable constructor params with explicit @Inject#24
msalvatti merged 1 commit into
mainfrom
fix/explicit-di-inject

Conversation

@msalvatti

Copy link
Copy Markdown
Member

Problem

The package ships a tsup/esbuild bundle. esbuild does not emit emitDecoratorMetadata (design:paramtypes = 0 in the built dist), 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:

Nest can't resolve dependencies of the QueueService (?, Symbol(BYMAX_QUEUE_RESOLVED_OPTIONS)). ... argument at index [0]

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 their useFactory inject arrays.

Verification

  • pnpm build (tsup) OK; pnpm typecheck OK; pnpm lint OK.
  • Unit suite: 258 passed / 21 suites.
  • DI boot repro against the built dist: Test.createTestingModule({ imports: [BymaxQueueModule.forRoot({ connection: { url } })] }).compile() now resolves QueueService (previously threw the dependency-resolution error).

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.
Copilot AI review requested due to automatic review settings July 9, 2026 21:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Inject where 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).

@msalvatti
msalvatti merged commit 4622027 into main Jul 9, 2026
18 checks passed
@msalvatti
msalvatti deleted the fix/explicit-di-inject branch July 9, 2026 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants