【问题标题】:NestJS v9: implement durable providersNestJS v9:实现持久提供者
【发布时间】:2022-11-18 01:26:39
【问题描述】:

[已解决] 我是 NestJS 的新手,我试图了解持久的提供者,但我无法让他们工作。

我的场景是我有一个具有一些逻辑的服务和两个实现相同接口以获取一些数据的提供者。根据我想使用 Provider1 或 Provider2 的自定义标头值,服务本身不必了解现有的提供程序实现。

因为我在一个请求范围的场景中,但我知道只有 2 个可能的依赖子树,我想使用持久的提供者,依赖不是为每个请求重新初始化,而是重用。

我按照官方 docs 中的描述设置了 ContextIdStrategy,它在每个请求上执行,但我错过了如何将我的提供者实现与在 ContextIdStrategy 中创建的 ContextSubtreeIds 连接的部分。

界面:

export abstract class ITest {
  abstract getData(): string;
}

实施:

export class Test1Provider implements ITest {
  getData() {
    return "TEST1";
  }
}
export class Test2Provider implements ITest {
  getData() {
    return "TEST2";
  }
}

服务:

@Injectable()
export class AppService {
  constructor(private readonly testProvider: ITest) {}

  getHello(): string {
    return this.testProvider.getData();
  }
}

控制器:

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getData(): string {
    return this.appService.getData();
  }
}

上下文 ID 策略:

const providers = new Map<string, ContextId>([
  ["provider1", ContextIdFactory.create()],
  ["provider2", ContextIdFactory.create()],
]);

export class AggregateByProviderContextIdStrategy implements ContextIdStrategy {
  attach(contextId: ContextId, request: Request) {
    const providerId = request.headers["x-provider-id"] as string;
    let providerSubTreeId: ContextId;

    if (providerId == "provider1") {
      providerSubTreeId = providers["provider1"];
    } else if (providerId == "provider2") {
      providerSubTreeId = providers["provider2"];
    } else {
      throw Error(`x-provider-id ${providerId} not supported`);
    }

    // If tree is not durable, return the original "contextId" object
    return (info: HostComponentInfo) =>
      info.isTreeDurable ? providerSubTreeId : contextId;
  }
}

主要的:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  ContextIdFactory.apply(new AggregateByProviderContextIdStrategy());
  await app.listen(3000);
}
bootstrap();

模块:

@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    {
      provide: ITest,
      useFactory: () => {
        // THIS IS THE MISSING PIECE. 
        // Return either Test1Provider or Test2Provider based on the ContextSubtreeId 
        // which is created by the ContextIdStrategy
        return new Test1Provider();
      },
    },
    AppService,
  ],
})
export class AppModule {}

【问题讨论】:

    标签: nestjs nestjs-providers


    【解决方案1】:

    缺少的部分是对 ContextIdStrategy 返回语句的修改:

    return {
      resolve: (info: HostComponentInfo) => {
        const context = info.isTreeDurable ? providerSubTreeId : contextId;
        return context;
      },
      payload: { providerId },
    }
    

    更改之后,可以将请求对象注入到模块中,它只包含 providerId 属性,基于此,useFactory 语句可以返回不同的实现

    【讨论】:

      猜你喜欢
      • 2016-10-21
      • 2011-08-18
      • 1970-01-01
      • 2021-12-29
      • 2018-03-30
      • 2011-12-10
      • 2020-07-19
      • 1970-01-01
      • 2013-08-29
      相关资源
      最近更新 更多