【发布时间】:2019-10-29 18:27:55
【问题描述】:
我一直在研究基于 NestJS 的 API,这是我遇到非常奇怪行为的代码的一部分。
问题:PagePartModule 未导入我添加到导入的任何模块(在本例中为 ImageModule),因此在尝试在 PagePartModule 的解析器中注入 ImageService 时,我变得未定义。请看下面的代码:
// page-part.module.ts
@Module({
imports: [ImageModule],
providers: [PagePartImageResolver],
})
export class PagePartModule {}
// page-part-image.resolver.ts
@Resolver(of => PagePartImage)
export class PagePartImageResolver {
constructor(
private readonly imageService: ImageService
) {}
@ResolveProperty('image', type => Image, { nullable: true })
async image(@Root() pagePart: PagePart) {
// NOTE: pagePart is filled with correct data
// ERROR: "Cannot read property 'find' of undefined",
// this.imageService is undefined
return await this.imageService.find({ id: pagePart.imageId });
}
}
// image.module.ts
@Module({
imports: [DataloaderModule],
providers: [ImageResolver, ImageService],
exports: [ImageService],
})
export class ImageModule {}
// image.service.ts
@Injectable()
export class ImageService {}
请注意,我是:
1) 在 ImageModule 导出装饰器中添加 ImageService
2) ImageService 用@Injectable()
装饰
3) 通过 PagePartModule 上的导入导入 ImageModule(提供 ImageService)
4)通过page-part-image.resolver.ts中的构造函数注入ImageService
我尝试过的:
- NestJS 在构建时不会抛出错误;一旦我查询解析器“图像”字段错误就会出现 - 说 Cannot read property 'find' of undefined -> imageService 未定义:未注入。
- 如果我将 ImageModule 注入其他模块,一切都会按预期工作。
- 即使我创建了一个作为 PagePartModule 一部分的服务,并将其放在 PagePartModule 提供程序中,它仍然没有注入指定的解析器 - 这很奇怪(但尝试将创建的服务再次导入其他模块按预期工作)。
- "emitDecoratorMetadata": true 存在于我的 tsconfig.json 中
我相信我正在做注射工作所需的一切。 (API 有十几个模块,我在其中使用相同的方法,并且按预期工作)
对于可能导致问题的任何指导,我将不胜感激。
"dependencies": {
"@nestjs/common": "^6.8.3",
"@nestjs/core": "^6.8.3",
"@nestjs/graphql": "^6.5.3",
"@nestjs/jwt": "^6.1.1",
"@nestjs/passport": "^6.1.0",
"@nestjs/platform-express": "^6.8.3",
"@nestjs/typeorm": "^6.2.0",
"apollo-server-express": "^2.9.6",
"aws-sdk": "^2.551.0",
"axios": "^0.19.0",
"crc-32": "^1.2.0",
"dataloader": "^1.4.0",
"dotenv": "^8.2.0",
"graphql": "^14.5.8",
"graphql-tools": "^4.0.5",
"helmet": "^3.21.1",
"lodash": "^4.17.15",
"nestjs-redis": "^1.2.3",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"pg": "^7.12.1",
"reflect-metadata": "^0.1.12",
"rimraf": "^2.6.2",
"rxjs": "^6.3.3",
"type-graphql": "^0.17.5",
"typeorm": "^0.2.19",
"uuid": "^3.3.3"
},
"devDependencies": {
"@nestjs/testing": "^6.0.0",
"@types/express": "^4.16.0",
"@types/jest": "^23.3.13",
"@types/node": "^10.14.22",
"@types/supertest": "^2.0.7",
"axios-mock-adapter": "^1.17.0",
"concurrently": "^4.1.0",
"jest": "^24.9.0",
"nodemon": "^1.19.4",
"prettier": "^1.15.3",
"supertest": "^3.4.1",
"ts-jest": "24.0.2",
"ts-loader": "^6.2.0",
"ts-node": "8.1.0",
"tsconfig-paths": "3.8.0",
"tslint": "5.16.0",
"typescript": "3.4.3",
"wait-on": "^3.2.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9",
"webpack-node-externals": "^1.7.2"
},
【问题讨论】:
-
从您的依赖项列表中,看起来某些依赖项可能不同步。您可能需要确保它们都处于相同的次要版本(我认为 6.8 是当前版本)
-
@JayMcDoniel 感谢您的提示,我刚刚这样做了,问题仍然存在。
-
因此,通常使用
ResolveProperty,您首先会调用Query或Mutation,这告诉GraphQL 如何解析该对象的此属性。看起来没有正在执行的查询,但我对此不是 100% 确定的。您是否验证了来自@Root()的属性也已定义?仍然不确定为什么ImageService会为空,其他一切看起来都正确。 -
抱歉,您看到的只是代码的一部分,可能会让您有些困惑。是的,@Root() 已正确填充(它是一个带有 imageId 的 PagePart 对象,应将其传递给 ImageService 以获得正确的图像),并且字段“image”(因此 ResolveProperty)通过其他查询解析,例如。文章,其中有 PageParts,其中一些具有“图像”,应该从注入的 ImageService 解析为图像; ImageService 实际上是未定义的,不为空;另外值得一提的是,我有一些请求范围的服务。 (它是一个多租户 API)。
-
嗯,这很奇怪。您有机会共享存储库吗?我想知道是否存在导致问题的更深层次的问题......
标签: dependency-injection nestjs