Repository: nestjs/nest

Issue #8894: Self-injection causes the app to get stuck in the initializing process without error
Created: 2022-01-11T13:06:33Z
Is there an existing issue for this?

 I have searched the existing issues

Current behavior
When an Injectable tries to inject itself in the constructor, the initializing process hangs without showing any error.
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  constructor(private readonly appService: AppService) {}
  getHello(): string {
    return 'Hello World!';
  }
}
App's logs:
[12:49:52 PM] File change detected. Starting incremental compilation...
api_1       | 
api_1       | [12:49:53 PM] Found 0 errors. Watching for file changes.
api_1       | 
api_1       | For help, see: https://nodejs.org/en/docs/inspector
api_1       | [Nest] 182  - 01/11/2022, 12:49:54 PM     LOG [NestFactory] Starting Nest application...
api_1       | [Nest] 182  - 01/11/2022, 12:49:54 PM     LOG [InstanceLoader] PrismaModule dependencies initialized +119ms
api_1       | [Nest] 182  - 01/11/2022, 12:49:54 PM     LOG [InstanceLoader] UsersModule dependencies initialized +2ms
Minimum reproduction code
https://codesandbox.io/s/friendly-lalande-ni9oq
Steps to reproduce
No response
Expected behavior
Nest should throw an error describing that the provider cannot inject itself.
Package

 I don't know. Or some 3rd-party package
 @nestjs/common
 @nestjs/core
 @nestjs/microservices
 @nestjs/platform-express
 @nestjs/platform-fastify
 @nestjs/platform-socket.io
 @nestjs/platform-ws
 @nestjs/testing
 @nestjs/websockets
 Other (see below)

Other package
No response
NestJS version
8.1.9
Packages versions
{
  "name": "server",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug 0.0.0.0:9229 --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/common": "^8.0.0",
    "@nestjs/core": "^8.0.0",
    "@nestjs/mapped-types": "*",
    "@nestjs/platform-express": "^8.0.0",
    "@prisma/client": "^3.7.0",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.13.2",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^8.0.0",
    "@nestjs/schematics": "^8.0.0",
    "@nestjs/testing": "^8.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "27.0.2",
    "@types/node": "^16.0.0",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "^27.2.5",
    "prettier": "^2.3.2",
    "prisma": "^3.7.0",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "^27.0.3",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "^3.10.1",
    "typescript": "^4.3.5"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}
Node.js version
v16.13.1
In which operating systems have you tested?

 macOS
 Windows
 Linux

Other
No response

Duplicate issue #9245: A class injecting a provider with the same token name fails injection
Created: 2022-02-22T22:42:56Z
Is there an existing issue for this?

 I have searched the existing issues

Current behavior
It turns out that right now, if a class (AppService) injects a dependency that has the same name (@Inject('AppService')), Nest will throw an error: Nest can't resolve dependencies of the AppService (?). Please make sure that the argument AppService at index [0] is available in the AppModule context.
I assume this is to prevent self injecting loops that will never actually resolve (class AppService injects class AppService inject class AppService etc).
This is happening here: https://github.com/nestjs/nest/blob/master/packages/core/injector/injector.ts#L434
Minimum reproduction code
https://github.com/jmcdo29/self-injection
Steps to reproduce
git clone git@github.com/jmcdo29:self-injection.git
cd self-injection
npm i
npm run start:dev
# observe error

Expected behavior
Nest should only throw an error if there are no specific providers using the custom provider syntax that have the same provider name as the class.
Package

 I don't know. Or some 3rd-party package
 @nestjs/common
 @nestjs/core
 @nestjs/microservices
 @nestjs/platform-express
 @nestjs/platform-fastify
 @nestjs/platform-socket.io
 @nestjs/platform-ws
 @nestjs/testing
 @nestjs/websockets
 Other (see below)

Other package
No response
NestJS version
8.3.1
Packages versions
platform-express version : 8.3.1
schematics version       : 8.0.6
testing version          : 8.3.1
common version           : 8.3.1
core version             : 8.3.1
cli version              : 8.2.1

Node.js version
16.13.0
In which operating systems have you tested?

 macOS
 Windows
 Linux

Other
Motivation for the "fix"
I've seen several users in the Discord create a wrapper class to create a custom repository via something like
@Injectable()
export class FooRepository {
  constructor(@InjectRepository(Foo) private readonly fooRepo: Repository<Foo>) {}
}
This results in the error message above. While I don't think this approach is necessary, we shouldn't necessarily be limiting, especially as Nest v8 allows for injecting classes by reference and not just by name anymore.
If this is still the intention, we should make a mention in the docs that providers cannot inject providers with the same name. Namely, class providers will not be able to @Inject(ProviderWithTheSameNameAsClass)

Closing comment (2022-02-23T09:26:31Z): Yeah that's a duplicate of #8894