【问题标题】:Unable to inject a chosen custom repository in a module无法在模块中注入选定的自定义存储库
【发布时间】:2022-01-19 19:13:44
【问题描述】:

当前行为

我正在尝试应用 SOLID 原则,因此将我的服务与 TypeOrm 分离。 好处是我可以将InMemoryRepository 用于测试目的,将TypeOrmRepository 用于实际生产代码。

目前,我无法将自定义 TypeOrm 存储库作为任何随机提供程序注入。我怀疑处理@InjectRepository()TypeOrm 的特定行为会干扰这里。 然而,我可以毫无问题地将我的 In Memory 存储库注入到我的单元测试中。

[Nest] 12311   - 18/09/2021 à 06:22:43   [ExceptionHandler] Cannot read property 'save' of undefined
TypeError: Cannot read property 'save' of undefined
    at TypeOrmWorkoutRepository.Object.<anonymous>.Repository.save (/Users/arthurmehmetoglu/Development/CorpoSano/back/src/repository/Repository.ts:150:29)
    at WorkoutService.create (/Users/arthurmehmetoglu/Development/CorpoSano/back/src/workout/workout.service.ts:30:35)
    at WorkoutResolver.create (/Users/arthurmehmetoglu/Development/CorpoSano/back/src/workout/workout.resolver.ts:22:32)
    at /Users/arthurmehmetoglu/Development/CorpoSano/back/node_modules/@nestjs/core/helpers/external-context-creator.js:69:33
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at target (/Users/arthurmehmetoglu/Development/CorpoSano/back/node_modules/@nestjs/core/helpers/external-context-creator.js:76:28)
    at /Users/arthurmehmetoglu/Development/CorpoSano/back/node_modules/@nestjs/core/helpers/external-proxy.js:9:24
[Nest] 12311   - 18/09/2021 à 06:22:43   [ExceptionHandler] Cannot read property 'findOne' of undefined +45ms
TypeError: Cannot read property 'findOne' of undefined
    at TypeOrmWorkoutRepository.Object.<anonymous>.Repository.findOne (/Users/arthurmehmetoglu/Development/CorpoSano/back/src/repository/Repository.ts:370:29)
    at TypeOrmWorkoutRepository.findById (/Users/arthurmehmetoglu/Development/CorpoSano/back/src/workout/repositories/typeorm-workout.repository.ts:12:17)
    at WorkoutService.fillWorkoutWithExercises (/Users/arthurmehmetoglu/Development/CorpoSano/back/src/workout/workout.service.ts:38:50)
    at WorkoutResolver.fillWorkoutWithExercises (/Users/arthurmehmetoglu/Development/CorpoSano/back/src/workout/workout.resolver.ts:32:32)
    at /Users/arthurmehmetoglu/Development/CorpoSano/back/node_modules/@nestjs/core/helpers/external-context-creator.js:69:33
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at target (/Users/arthurmehmetoglu/Development/CorpoSano/back/node_modules/@nestjs/core/helpers/external-context-creator.js:76:28)
    at /Users/arthurmehmetoglu/Development/CorpoSano/back/node_modules/@nestjs/core/helpers/external-proxy.js:9:24

更多详情请在下方输入代码。

输入代码

workout.module.ts

import ...

@Module({
  imports: [TypeOrmModule.forFeature([Workout])],
  providers: [
    {
      provide: EXERCISE_REPOSITORY,
      useClass: TypeOrmExerciseRepository,
    },
    {
      provide: WORKOUT_REPOSITORY,
      useClass: TypeOrmWorkoutRepository,
    },
    WorkoutResolver,
    WorkoutService,
  ],
})
export class WorkoutModule {}

workout.service.ts

...

@Injectable()
export class WorkoutService {
  constructor(
    @Inject(WORKOUT_REPOSITORY)
    private readonly workoutRepository: WorkoutRepository,
    @Inject(EXERCISE_REPOSITORY)
    private readonly exerciseRepository: ExerciseRepository,
  ) {}
  
...

workout.service.spec.ts

...

describe('Workout Service', () => {
  let workoutService: WorkoutService
  let workoutRepository: WorkoutRepository
  let exerciseRepository: ExerciseRepository

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        {
          provide: WORKOUT_REPOSITORY,
          useClass: InMemoryWorkoutRepository,
        },
        {
          provide: EXERCISE_REPOSITORY,
          useClass: InMemoryExerciseRepository,
        },
        WorkoutService,
      ],
    }).compile()

    workoutService = module.get<WorkoutService>(WorkoutService)
    workoutRepository = module.get<WorkoutRepository>(WORKOUT_REPOSITORY)
    exerciseRepository = module.get<ExerciseRepository>(EXERCISE_REPOSITORY)
  })

  it('should be defined', () => {
    expect(workoutService).toBeDefined()
  })
  
  ...

workout-repository.interface.ts

import { Workout } from '../entities/workout.entity'
import { Exercise } from '../../exercise/entities/exercise.entity'

export const WORKOUT_REPOSITORY = 'WorkoutRepository'

export interface WorkoutRepository {
  findById(id: string): Promise<Workout>
}

in-memory-exercise.repository.ts

export class InMemoryWorkoutRepository implements WorkoutRepository {
  findById(id: string): Promise<Workout> {
    return Promise.resolve(undefined)
  }
}

typeorm-workout.repository.ts

@EntityRepository(Workout)
export class TypeOrmWorkoutRepository
  extends Repository<Workout>
  implements WorkoutRepository
{
  async findById(workoutId: string): Promise<Workout> {
    return this.findOne(workoutId)
  }
}

环境

嵌套版本:7.6.0

对于工具问题:

  • 节点版本:v14.16.1
  • 平台:Mac

其他: 有关我正在努力实现的目标的更多详细信息,我的工作受到了这些文章的启发:

PS:我试图将代码简化为需要理解的内容。

【问题讨论】:

标签: typescript nestjs typeorm solid-principles in-memory-database


【解决方案1】:

我实际上用useExtisting 解决了这个问题,如下所示:

 import { Module } from '@nestjs/common'
 import { getRepositoryToken, TypeOrmModule } from '@nestjs/typeorm'
 import { WorkoutResolver } from './workout.resolver'
 import { WorkoutService } from './workout.service'
 import { TypeOrmExerciseTemplateRepository } from '../exercise/repositories/type-orm-exercise-template.repository'
 import { TypeOrmWorkoutRepository } from './repositories/workout.typeorm.repository'
 import { TypeOrmExerciseRepository } from '../exercise/repositories/type-orm-exercise.repository'
 import { WORKOUT_REPOSITORY } from './repositories/workout.repository.interface'
 import { EXERCISE_TEMPLATE_REPOSITORY } from '../exercise/repositories/exercise-template-repository.interface'
 import { EXERCISE_REPOSITORY } from '../exercise/repositories/exercise-repository.interface'
 import { TypeOrmSessionRepository } from '../session/repositories/session.typeorm.repository'
 import { FillWorkoutWithExercisesUseCase } from './use-cases/fill-workout-with-exercises.use-case'
 
 @Module({
   imports: [
     TypeOrmModule.forFeature([
       TypeOrmExerciseTemplateRepository,
       TypeOrmExerciseRepository,
       TypeOrmWorkoutRepository,
       TypeOrmSessionRepository,
     ]),
   ],
   providers: [
     {
       provide: WORKOUT_REPOSITORY,
       useExisting: getRepositoryToken(TypeOrmWorkoutRepository),
     },
     {
       provide: EXERCISE_REPOSITORY,
       useExisting: getRepositoryToken(TypeOrmExerciseRepository),
     },
     {
       provide: EXERCISE_TEMPLATE_REPOSITORY,
       useExisting: getRepositoryToken(TypeOrmExerciseTemplateRepository),
     },
     WorkoutResolver,
     WorkoutService,
     FillWorkoutWithExercisesUseCase,
   ],
 })
 export class WorkoutModule {}

【讨论】:

    猜你喜欢
    • 2019-09-30
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 2016-08-16
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多