Dependency injection NestJS-关于服务模拟的问题
我目前正在用NestJS重写我们的普通节点API服务器,我遇到了以下问题:我有一个Dependency injection NestJS-关于服务模拟的问题,dependency-injection,mocking,nestjs,Dependency Injection,Mocking,Nestjs,我目前正在用NestJS重写我们的普通节点API服务器,我遇到了以下问题:我有一个CacheService,它充当redis的包装器,并被注入到各种其他服务中 现在,如果客户端请求包含一个自定义头(键:x-mock-redis,值:someRedisMockKey),并且如果服务器在调试模式下运行,而不是调用redis,则应返回模拟的json值(该值从名为someRedisMockKey的文件中读取) 我可以将我的CacheService的作用域设置为“Request”,并注入客户机请求,允许我
CacheService
,它充当redis的包装器,并被注入到各种其他服务中
现在,如果客户端请求包含一个自定义头(键:x-mock-redis
,值:someRedisMockKey
),并且如果服务器在调试模式下运行,而不是调用redis,则应返回模拟的json值(该值从名为someRedisMockKey
的文件中读取)
我可以将我的CacheService
的作用域设置为“Request”,并注入客户机请求,允许我检查mocking头是否存在,如果在调试模式下运行,则返回mocked值。
但我发现这是违反直觉的,因为我的逻辑违反了单一责任原则,不应该在生产模式下运行。另外,我希望我的CacheService
具有默认范围,而不是“请求”
如何更优雅地完成这项工作,有什么建议吗?事先,如果我误解了问题或限制,请原谅,我会尝试解释它们,并指出应该是什么样子,我想
- 生产总是使用Redis
- 您可以在不同的端口上设置应用程序实例,使其与“暂存”(或其他)应用程序实例完全分离
缓存模块的自定义提供程序
import * as redis from 'redis'
import { INTERNAL_CACHE_CLIENT, INTERNAL_CACHE_MODULE } from './cache.constants'
import { CacheModuleAsyncOptions, InternalCacheOptions } from './cache.module'
import CacheClientRedis from './client/cache-client-redis'
// ...
export const createAsyncClientOptions = (options: CacheModuleAsyncOptions) => ({
provide: INTERNAL_CACHE_MODULE,
useFactory: options.useFactory,
inject: options.inject,
})
export const createClient = () => ({
provide: INTERNAL_CACHE_CLIENT,
useFactory: (options: InternalCacheOptions) => {
const { production, debug, noCache, ...redisConfig } = options
// pardon for the ifs ; )
if (noCache) {
return new CacheClientInMemory()
}
if (production) {
return new CacheClientRedis(redis.createClient(redisConfig))
}
if (debug) {
return new MockedCache()
}
return new CacheClientMemory()
},
inject: [INTERNAL_CACHE_MODULE],
})
正如所注意到的,您可以在CacheClient周围使用任何包装器,在您的情况下,这些包装器将为文件中的数据提供服务。为简单起见,由任何缓存客户端实现的接口示例可以是:
export interface CacheClient {
set: (key: string, payload: string) => Promise<boolean>
get: (key: string) => Promise<string | null>
del: (key: string) => Promise<boolean>
}
请随时指出它是否仍然违反原则,或者您确实需要在运行时做出决定
干杯 谢谢你有趣的输入。问题是我真的需要决定在运行时使用什么(例如,正如我试图描述的,当客户端发送特定的头时)。有什么想法吗?将把责任转移到CacheClient上,但这与服务本身非常相似,不过在这种情况下,客户端实现将作为一种策略:耸耸肩:
constructor(
@Inject(INTERNAL_CACHE_CLIENT) private readonly cacheClient: CacheClient) {
}