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],
})
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…