contribution-provider.ts 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import { type interfaces } from 'inversify';
  6. export const ContributionProvider = Symbol('ContributionProvider');
  7. export interface ContributionProvider<T extends object> {
  8. getContributions(): T[];
  9. forEach(fn: (v: T) => void): void;
  10. }
  11. class ContainerContributionProviderImpl<T extends object> implements ContributionProvider<T> {
  12. protected services: T[] | undefined;
  13. constructor(
  14. protected readonly container: interfaces.Container,
  15. protected readonly identifier: interfaces.ServiceIdentifier<T>
  16. ) {}
  17. forEach(fn: (v: T) => void): void {
  18. this.getContributions().forEach(fn);
  19. }
  20. getContributions(): T[] {
  21. if (!this.services) {
  22. const currentServices: T[] = [];
  23. let { container } = this;
  24. if (container.isBound(this.identifier)) {
  25. try {
  26. currentServices.push(...container.getAll(this.identifier));
  27. } catch (error: any) {
  28. console.error(error);
  29. }
  30. }
  31. this.services = currentServices;
  32. }
  33. return this.services;
  34. }
  35. }
  36. export function bindContributionProvider(bind: interfaces.Bind, id: symbol): void {
  37. bind(ContributionProvider)
  38. .toDynamicValue((ctx) => new ContainerContributionProviderImpl(ctx.container, id))
  39. .inSingletonScope()
  40. .whenTargetNamed(id);
  41. }