0
votes

I created a class named: S3Service which is responsible for uploading and deleting objects from S3 (pretty much images), since I wish to use the "service" (is there a better name?) in other modules, I decided to create a custom module: UtilsModule where I hope to create a set of reusable shared classes. I managed to export this class from my UtilsModule.

@Injectable()
export class S3Service {
  constructor(@InjectS3() private readonly client: S3) {}
  async removeObject(): Promise<S3.DeleteObjectOutput> {}
  async uploadObject(): Promise<S3.ManagedUpload.SendData> {}
}
@Module({
  providers: [S3Service],
  exports: [S3Service],
})
export class UtilsModule {}

I did import this UtilsModule into the app module.

@Module({
  imports: [
    // Other modules here
    UtilsModule,
  ],
})
export class AppModule {}

And then import it into a module which needs to upload or remove objects from S3.

@Module({
  imports: [
    // Other modules
    TypeOrmModule.forFeature([ProfileRepository]),
    UtilsModule,
  ],
  controllers: [ProfileController],
  providers: [ProfileService],
})
export class ProfileModule {}

And finally inject it using the decorator @Inject into the desired repository.

@EntityRepository(Profile)
export class ProfileRepository extends Repository<Profile> {
  constructor(
    @Inject() private s3Service: S3Service,
  ) {
    super();
  }
}

Here my application does compile but when I invoke this service via a Post request, a Internal Server Error is thrown, I started debugging with breakpoints in this "service" but it looks like the uploadObject function is undefined.

I read this thread and apparently TypeORM repositories are not subject for DI, is there a workaround this? Should I then instantiate this class in the repository?

1
I am a little bit worried seeing you inject services in your repository. Is it a good practice to do so. NOT SURE. You can import repositories inside your repository. Try doing so Maybe it can help.user10057478
Not familiar with this constructor(@InjectS3() private readonly client: S3) {} Do you import it like this while dealing with S3?user10057478
It's a NPM package, I was using it in the repository, but I decided to move it out. If this is a bad practice I may just inject it into my service and upload objects from there, I just thought having it available in the repository would be a "cleaner" solution codewiseJeremy
Yes you should not inject services into your repository, as far as it's possible.user10057478

1 Answers

0
votes

I ended up discarding injecting a service into my repository since this would be considered a bad practice, and it looks like nest doesn't allow injecting into a TypeORM repository class.

For a solution I needed to set this S3Service (remember to use the Injectable() decorator) as a provider of my UtilsModule and export it.

@Module({
  providers: [S3Service],
  exports: [S3Service],
})
export class UtilsModule {}

Import it into the AppModule and into the module where it's needed.

@Module({
  imports: [
    // Other modules
    UtilsModule,
  ],
})
export class ProfileModule {}

Then I injected a repository into my service and access the db entity directly, this actually cleaned up my code quite a bit. Finally use it as a dependency in the constructor.

export class ProfileService {
  constructor(
    @InjectRepository(Profile)
    private profileRepository: Repository<Profile>,
    private s3Service: S3Service,
  ) {}
}