From harness-claude
Master NestJS DI container with tokens, useClass/useValue/useFactory providers, and async initialization. Helps resolve 'Cannot resolve dependencies' errors.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:nestjs-dependency-injectionThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Master NestJS DI container with tokens, useClass/useValue/useFactory providers
Master NestJS DI container with tokens, useClass/useValue/useFactory providers
Standard provider (shorthand): providers: [MyService] — NestJS creates one singleton instance, injected by class type.
useClass — swap implementations:
providers: [
{ provide: MyService, useClass: process.env.NODE_ENV === 'test' ? MockMyService : MyService },
];
export const STRIPE_CLIENT = 'STRIPE_CLIENT';
providers: [
{ provide: STRIPE_CLIENT, useValue: new Stripe(process.env.STRIPE_KEY!) }
]
// inject with @Inject token
constructor(@Inject(STRIPE_CLIENT) private stripe: Stripe) {}
providers: [
{
provide: DATABASE_CONNECTION,
useFactory: async (config: ConfigService): Promise<DataSource> => {
const ds = new DataSource({ url: config.get('DATABASE_URL') });
await ds.initialize();
return ds;
},
inject: [ConfigService],
},
];
Symbol-based or class-based tokens over plain strings to avoid collisions:export const MAIL_OPTIONS = new InjectionToken<MailOptions>('MailOptions');
@Inject(TOKEN) when the token is not a class:constructor(@Inject(MAIL_OPTIONS) private options: MailOptions) {}
@Optional() when a provider may not be registered: constructor(@Optional() @Inject(CACHE) private cache?: Cache) {}.NestJS uses a hierarchical IoC container built on top of Reflect metadata. When you add a class to providers, the container reads its constructor parameter types via TypeScript's emitDecoratorMetadata and resolves each dependency recursively.
Token resolution: A provider token can be a class, a string, a Symbol, or an InjectionToken<T>. The container matches the provide key to the @Inject() token (or the constructor type for class providers). Mismatched tokens are the second most common DI error after missing exports.
Scopes and singleton behavior: Default (singleton) scope means useFactory runs once at app startup. REQUEST scope runs the factory (or constructor) per request — useful for per-request database connections or tenant-aware clients.
Testing: overrideProvider(MyService).useValue(mockService) in Test.createTestingModule() replaces any token with a mock without touching the module graph. This is the cleanest way to unit-test controllers and services.
ModuleRef.resolve() for dynamic resolution: When you need to resolve a provider at runtime (e.g., strategy pattern where the concrete implementation depends on runtime data), inject ModuleRef and call moduleRef.resolve(SomeService).
https://docs.nestjs.com/fundamentals/custom-providers
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeGuides NestJS dependency injection using class, value, factory providers, modules, decorators, scopes, and best practices for modular Node.js apps.
Implements Angular dependency injection using providers (useClass, useValue, useFactory), injectors, and services for modular, testable applications.
Organizes NestJS applications with cohesive feature modules, controlled exports, and composable dynamic configurations. Useful when structuring providers, avoiding circular dependencies, or building reusable configurable modules.