#Inject CACHE_MANAGER to custom service provider

10 messages · Page 1 of 1 (latest)

tough shale
#

Hi there,
I would love to have some help injecting the cache manager to my custom service from my module class.

Here is the code I currently have:

@Module({
  imports: [
    CacheModule.registerAsync({
      isGlobal: true,
    }),
  ],
  providers: [CustomService],
  exports: [CustomService],
})
export class CustomModule {
  public static registerAsync(options: CustomOptions): DynamicModule {
    const provider: Provider = {
      provide: CustomService,
      useFactory: (
        options: CustomOptions,
        cacheManager: Cache,
        httpService: HttpService
      ) => new CustomService(cacheManager, httpService),
      inject: [CACHE_MANAGER, HttpService],
    };

    return {
      global: true,
      module: CustomModule,
      imports: [...(options.imports ?? [])],
      providers: [provider],
      exports: [provider],
    };
  }
}

@Injectable()
export class CustomService {
  constructor(
    @Inject(CACHE_MANAGER) private cacheManager: Cache,
    private readonly httpService: HttpService
  ) {}
}

However by doing that I've got the next error message:

Nest cannot export a provider/module that is not a part of the currently processed module (CustomModule). Please verify whether the exported CACHE_MANAGER is available in this particular context.

Possible Solutions:
- Is CACHE_MANAGER part of the relevant providers/imports within CustomModule?

Hope you can help me figured out this issue 😉

cursive topaz
#

Is this an issue when using the module like CustomModule.registerAsync?

tough shale
#

Yes indeed!
But I need to use it with registerAsync because I'm passing config env variables that are not in my example.

cursive topaz
#

Okay. This is one of those oddities of how dynamic modules work. I believe thatt because you inject the CACHE_MANAGER in the inject array, you also need to have CacheModule.register() in the imports of the dynamic module, not just the @Module() metadata. Could be wrong, but give it a shot

tough shale
#

Okay will test that!
Other part of code I'm not 100% sure is cacheManager: Cache, when trying to inject it to my service

cursive topaz
#

With useFactory the inject array acts like the constructor, so you pass the injection tokens to the inject array you expect them to be passed to useFactory. In your case, you're missing the options before the CACHE_MANAGER

tough shale
#

Oh! Yes indeed, thanks

#

Everything seems to be working like a charm now, thanks for the help and assist @cursive topaz . The main issue was related to CacheModule.register()

opaque jay
#

Im running into this same issue now, also using CustomModule.registerAsync because of environment vars. What ended up being your work around @emulienfou @cursive topaz

#
import { Module } from '@nestjs/common'
import { CacheModule } from '@nestjs/cache-manager'
import { ConfigModule, ConfigService } from '@nestjs/config'
import * as redisStore from 'cache-manager-redis-store'

@Module({
    imports: [
        CacheModule.registerAsync({
            imports: [ConfigModule],
            useFactory: async (configService: ConfigService) => ({
                isGlobal: true,
                store: redisStore,
                host: configService.get<string>('cache.host') || 'localhost',
                port: configService.get<number>('cache.port') || 6379,
            }),
            inject: [ConfigService],
        }),
    ],
})
export class AppCacheModule {}