routing-controllers: fix: TypeDI integration not working as expected on docs
Description
Cannot use TypeDI as explained on the README for basic services.
Obviously, it is written that it only requires the @Service on service side (seems legit), but this actually doesn’t work without telling @Service before the controller as well.
Minimal code-snippet showcasing the problem
Controller snippet
import { Service } from 'typedi'
import { Get, JsonController, Param, State } from 'routing-controllers'
import { CollaboratorService } from '../services/CollaboratorService'
@JsonController('/service/:serviceId/collaborator')
@Service() // This shouldn't be required as described on the README, but it is actually required to run the app as expected
export class CollaboratorController {
constructor(private collaboratorService: CollaboratorService) { }
@Get('/')
async getCollaborators (@State('user') user: User, @Param('serviceId') serviceId: number) {
return await this.collaboratorService.getCollaborators(
user.id,
serviceId
)
}
Actual service snippet
import { Service } from 'typedi'
@Service()
export class CollaboratorService {
async getCollaborators (userId: number, serviceId: number) {
...
}
}
Expected behavior
I’ve imported everything and created the DI Container before the app, the Controller should be working without the @Service decorator declaration.
Actual behavior
It doesn’t, if I try to run the code without the @Service decorator on top of the Controller, I’ll get the following error:
{
"name": "ServiceNotFoundError",
"message": "Service with \"MaybeConstructable<CollaboratorService>\" identifier was not found in the container. Register it before usage via explicitly calling the \"Container.set\" function or using the \"@Service()\" decorator.",
"stack": "ServiceNotFoundError: Service with \"MaybeConstructable<CollaboratorService>\" identifier was not found in the container. Register it before usage via explicitly calling the \"Container.set\" function or using the \"@Service()\" decorator.\n at ContainerInstance.get (L:\\...\\node_modules\\typedi\\cjs\\container-instance.class.js:45:15)\n at Object.value (L:\\...\\node_modules\\typedi\\cjs\\decorators\\inject.decorator.js:31:42)\n at L:\\...\\node_modules\\typedi\\cjs\\container-instance.class.js:286:58\n at Array.forEach (<anonymous>)\n at ContainerInstance.applyPropertyHandlers (L:\\...\\node_modules\\typedi\\cjs\\container-instance.class.js:280:46)\n at ContainerInstance.getServiceValue (L:\\...\\node_modules\\typedi\\cjs\\container-instance.class.js:240:18)\n at ContainerInstance.get (L:\\...\\node_modules\\typedi\\cjs\\container-instance.class.js:29:25)\n at Function.get (L:\\...\\node_modules\\typedi\\cjs\\container.class.js:28:36)\n at Object.getFromContainer (L:\\...\\node_modules\\routing-controllers\\container.js:40:42)\n at ControllerMetadata.getInstance (L:\\...\\node_modules\\routing-controllers\\metadata\\ControllerMetadata.js:26:28)",
"normalizedIdentifier": "MaybeConstructable<CollaboratorService>"
}
I don’t know if this is an upstream issue or not.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 16
- Comments: 16 (7 by maintainers)
I had to update ~60 classes to add
@Serviceeverywhere. This is just crazy. Couldn’t@Controllerdecorator automatically register controller/middleware classes with the provided DIC? I guess, this should be just a couple of lines of code in the library.Let’s keep this open for tracking. I think we may auto-register services, but we need to discuss this further.
I hate to ask, but: how does something like this sound when the developer says it out loud?
A meme for the ages.
Services everywhere.
This is what I’m using to save me from writing more code than necessary 😁 :
Hi!
This is the expected behavior. Since TypeDI 0.9.0 it won’t create instances for unknown classes, so you need to decorate your classes. This needs to be documented and also I believe a fix is possible as routing-controller can auto-register them in its own decrator.
@aaarichter In SemVer, going from version 0.x.y to 0.x+1.0 is considered a major bump. NPM also handles it as such, e.g. depending on
typedi@^0.8.0would install the latest 0.8.x version, not 0.9.x.