gpt4 book ai didi

dependency-injection - 如何在 loopback 4 中进行方法注入(inject)

转载 作者:行者123 更新时间:2023-12-05 04:59:13 25 4
gpt4 key购买 nike

我想创建一个方法 checkAddressEnterContestBefore 来检查一些要求。此功能需要连接到数据库(mysql),但我无法注入(inject)存储库。在这种情况下我能做什么?

import { Contest } from '../models';
import { CONTEST_STATUS } from './constants';
import { ContestEntryRepository } from '../repositories';
import { inject } from '@loopback/core';

export function checkEnterContest(contest: Contest, address: string): boolean {
....
if (!checkAddressEnterContestBefore(contest, address)) return false;
...
return true;
}

export async function checkAddressEnterContestBefore(
@inject(ContestEntryRepository) contestEntryRepository: ContestEntryRepository,
contest: Contest, address: string): Promise<boolean> {
const contestEntry = await contestEntryRepository.findOne({
where: {
and: [
{ contestId: contest.id },
{ address: address }
]
}
});

return contestEntry == null
}

最佳答案

依赖注入(inject)有两部分:

  1. 接收依赖项的代码用@inject装饰器装饰以指定要注入(inject)的内容
  2. 此类代码的调用者必须解决来自 IoC 容器的依赖性

在您的代码片段中,您正在装饰 checkAddressEnterContestBefore 以通过 DI 接收一些参数(这是我上面列表中的第一项)。代码是否编译?据我所知,装饰器不能应用于常规函数,只能应用于类成员(静态或实例级)。

一个使用静态类方法的例子:

export class CheckAddressEnterContestBefore {
static async run(
@inject(ContestEntryRepository) contestEntryRepository: ContestEntryRepository,
contest: Contest, address: string): Promise<boolean> {
const contestEntry = await contestEntryRepository.findOne({
where: {
and: [
{ contestId: contest.id },
{ address: address }
]
}
});

return contestEntry == null
}
}

现在 checkEnterContest 没有实现依赖注入(inject)/解析(我上面列表中的第二项)。

LoopBack 提供了一个辅助函数 invokeMethod,您可以使用它来调用具有依赖项注入(inject)的方法。您将需要当前的 Context 对象作为从中获取依赖项的来源。

import {invokeMethod} from '@loopback/core';

export function checkEnterContest(ctx: Context, contest: Contest, address: string): boolean {
....
const checkResult = await invokeMethod(
CheckAddressEnterContestBefore,
'run',
// context for resolving dependencies
ctx,
// additional (non-injected) arguments
[contest, address],
);

if (!checkResult) return false;
...
return true;
}

就我个人而言,我认为它是一种反模式,可以从代码库深处的上下文中解决依赖关系。相反,我建议使用常规函数/方法参数在代码库的不同部分之间传递依赖关系,并仅在顶层使用基于 @inject 的依赖注入(inject)——通常在 Controller 方法中。

这将使您的代码更易于单独测试,因为每个函数都明确了它需要哪些依赖项,如果您的测试未提供所有必需的依赖项,编译器会在编译时警告您。当您从上下文中解析依赖项时,您只会在运行时发现缺少的依赖项,因为您的测试没有在上下文中绑定(bind)它们而无法解析它们。

话虽如此,以下是我将如何重写您的代码:

export function checkEnterContest(
contestEntryRepository: ContestEntryRepository,
contest: Contest,
address: string
): boolean {
....
if (!checkAddressEnterContestBefore(contestEntryRepository, contest, address)) return false;
...
return true;
}

export async function checkAddressEnterContestBefore(
contestEntryRepository: ContestEntryRepository,
contest: Contest,
address: string
): Promise<boolean> {
const contestEntry = await contestEntryRepository.findOne({
where: {
and: [
{ contestId: contest.id },
{ address: address }
]
}
});

return contestEntry == null
}

根据您喜欢的代码结构,将 checkEnterContestcheckAddressEnterContestBefore 实现为 ContestEntryRepository 方法可能会更好。

关于dependency-injection - 如何在 loopback 4 中进行方法注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63614378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com