【发布时间】:2021-12-17 00:48:13
【问题描述】:
我面临一个问题,其中我有很多存储库(它们是实现一个接口的 TS 类,它们是 typeorm 存储库类)并且我使用 TSyringe 来处理我的所有依赖项在我的 API 中
这是一个存储库的示例
import { getRepository, Repository } from 'typeorm';
import SafeUsd from '@modules/currencies/infra/typeorm/entities/SafeUsd';
import ICreateSafeUsdDTO from '@modules/currencies/dtos/ICreateSafeUsdDTO';
import ISafeUsdRepository from '@modules/currencies/repositories/ISafeUsdRepository';
import { classToClass } from 'class-transformer';
import IUpdateSafeUsdDTO from '@modules/currencies/dtos/IUpdateSafeUsdDTO';
export default class SafeUsdRepository implements ISafeUsdRepository {
private ormRepository: Repository<SafeUsd>;
constructor() {
this.ormRepository = getRepository(SafeUsd);
}
async create(data: ICreateSafeUsdDTO): Promise<SafeUsd> {
const safeUsd = this.ormRepository.create(data);
await this.ormRepository.save(safeUsd);
return classToClass(safeUsd);
}
async update({
safeUsd,
value,
acceptable_variance,
margin,
}: IUpdateSafeUsdDTO): Promise<SafeUsd> {
if (margin !== undefined) {
safeUsd.margin = margin;
}
if (value !== undefined) {
safeUsd.value = value;
}
if (acceptable_variance !== undefined) {
safeUsd.acceptable_variance = acceptable_variance;
}
await this.ormRepository.save(safeUsd);
return classToClass(safeUsd);
}
async findOne(): Promise<SafeUsd | undefined> {
const safeUsd = await this.ormRepository.findOne();
return classToClass(safeUsd);
}
}
之后,我将所有存储库注册到一个文件中,在 "shared/container/repositories/index.ts"
内import { container } from 'tsyringe';
import ICurrenciesRepository from '@modules/currencies/repositories/ICurrenciesRepository';
import CurrenciesRepository from '@modules/currencies/infra/typeorm/repositories/CurrenciesRepository';
import ICurrenciesUrlRepository from '@modules/currencies/repositories/ICurrenciesUrlRepository';
import CurrenciesUrlRepository from '@modules/currencies/infra/typeorm/repositories/CurrenciesUrlRepository';
import ISafeUsdRepository from '@modules/currencies/repositories/ISafeUsdRepository';
import SafeUsdRepository from '@modules/currencies/infra/typeorm/repositories/SafeUsdRepository';
container.registerSingleton<ICurrenciesRepository>(
'CurrenciesRepository',
CurrenciesRepository,
);
container.registerSingleton<ICurrenciesUrlRepository>(
'CurrenciesUrlRepository',
CurrenciesUrlRepository,
);
container.registerSingleton<ISafeUsdRepository>(
'SafeUsdRepository',
SafeUsdRepository,
);
在我的应用程序中,我还有一些提供程序(它们基本上是第三方 API 的实现,例如 AWS、GoogleFirebase 等...)
我想做的是将我的一些存储库注入到我的提供程序中,然后我想注册由 TSyringe 容器解析的它们的实例。
当我尝试做我刚刚在上面写的事情时,问题就开始了。在使用 TSyring 容器注册我的存储库和提供程序时,我会这样做:
import './repositories';
import './providers';
其中有很多 TS 文件都执行 TSyringe container.registerSingleton、.resolve 或 .registerInstance 方法。
我总是收到这个错误:
Error: Cannot inject the dependency at position #2 of "BitfinexBrokerProvider" constructor.
Reason:No repository for "Currency" was found. Looks like this entity is not registered in current "default" connection?
此错误表示我的存储库尚未启动,因此当 TSyringe 尝试将它们注入我的 Providers 时,它们尚未与数据库建立连接,因此我收到此错误。如果我不将这些存储库注入到我的提供程序中,那么一切正常。
关于如何解决这个问题的任何想法?我想做的是:
- 首先解析并注册所有存储库单例,以便它们与数据库连接。
- 仅在此之后,注册所有提供者。
关于如何实现这一点的任何想法?我希望我已经清楚地解决了我的问题,请问你们是否有任何疑问,我将编辑帖子以使其更清楚。
提前致谢。
更新:我已尝试添加所有 TSyringe .registerSingleton() || .registerInstance() || .resolve(), 在一个 "setTimeout(() => {}, 3000)" 里面,它起作用了!正如我在问题中所说,我只需要稍等片刻,以便在我的存储库上建立数据库连接,然后再注入提供程序。
在这里你可以看到我做了什么
import { container } from 'tsyringe';
import BitfinexBrokerProvider from './implementations/BitfinexBrokerProvider';
import BrokerHandlerProvider from './implementations/BrokerHandlerProvider';
import FlowBTCBrokerProvider from './implementations/FlowBTCBrokerProvider';
import BitfinexChannelHandler from './implementations/websocket/bitfinex/ChannelHandler';
import IBrokerHandlerProvider from './models/IBrokerHandlerProvider';
import IBrokerProvider from './models/IBrokerProvider';
import IChannelHandler from './models/IChannelHandler';
setTimeout(() => {
container.registerSingleton<IBrokerProvider>(
'FlowBTCBrokerProvider',
FlowBTCBrokerProvider,
);
container.registerSingleton<IChannelHandler>(
'BitfinexChannelHandler',
BitfinexChannelHandler,
);
const bitfinexBrokerProvider = container.resolve(BitfinexBrokerProvider);
container.registerInstance<IBrokerProvider>(
'BitfinexBrokerProvider',
bitfinexBrokerProvider,
);
const brokerHandlerProvider = container.resolve(BrokerHandlerProvider);
container.registerInstance<IBrokerHandlerProvider>(
'BrokerProvider',
brokerHandlerProvider,
);
}, 3000);
虽然它有效,但我发现这个解决方案非常令人不快且不优雅。有没有更好的方法来实现更好的解决方案?
【问题讨论】:
标签: typescript singleton domain-driven-design typeorm tsyringe