Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
599 views
in Technique[技术] by (71.8m points)

javascript - Importing TypeScript modules with dependency injection in NestJS

In my NestJS application - I have TypeScript classes that have other classes and values injected into them. The only thing is that I'm importing the TypeScript classes with import statements, and also using the DI system to inject them. Is there some way to remove the import statements and just let the DI system handle it?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

TL;DR

  • import -> class reference
  • DI -> class instantiation
  • Matching by string token is possible, but class reference is preferred.

Encapsulation

The dependency injection system mainly handles the instantiation of the classes. This is great, because you do not need to care about the transitive dependencies that the class you want to inject requires.

Example: I want to use the UserService in my UserController. The UserService requires the UserModel for instantiation. However, this second-level dependency is hidden in the UserController. This is great because when the UserService gets a new dependency like a LoggingService, the UserController does not have to be changed.

So instead of

class UserController {
  constructor() {
    const userModel = new UserModel();
    this.userService = new UserService(userModel);
  }
}

you can just do

class UserController {
  // the transitive dependency on UserModel is hidden
  constructor(private userService: UserService) {}
}

Class Reference

But for the DI to know which service to inject you need some link from the @Inject declaration to an actual class to instantiate. Of course, this mechanism depends on the implementation of the DI system. The reference could be by name (string matching), by interface (DI decides which implementation to use: UserService -> UserServiceImpl / MockUserServiceImpl) or in the default case of nestjs directly by the class to be instantiated.

Although matching by name is possible in nestjs, matching by class is preferred because it makes refactoring much easier.

When you create a custom provider you can choose what kind of token you want to use for the matching. This is needed, when you want to inject a value (no class for matching)

const connectionProvider = {
  provide: 'Connection',
  useValue: connection,
};

@Module({
  providers: [connectionProvider],
})

or a dynamically instantiated class.

const configServiceProvider = {
  provide: ConfigService,
  useClass: process.env.NODE_ENV === 'development'
    ? DevelopmentConfigService
    : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...