typescript - Finnes det en måte å sende tilpassede parametere til useFactory DynamicModules i NestJs?


Jeg har et delt bibliotek som skal levere moduler til andre applikasjoner. Så jeg trenger dynamiske tilpassede parametere for å generere tilpassede forekomster for hver modul inne i en applikasjon.

Jeg har allerede åpnet en sak for dette i det offisielle repoet nestjs/issues/1965, men kanskje noen her kan gi meg noen ideer eller hjelpe meg med dette.

Jeg har allerede sett på nestjs-dokumentasjonen og også lest koden og problemene, men jeg kan ikke finne en måte å dynamisk få parametere fra instansieringsprosessen for å generere tilpassede instanser av hva som helst jeg vil.

Så i utgangspunktet det jeg trenger er å gi en streng som kan komme inn i instansieringsprosessen slik at den returnerte instansen vil bruke strengen til å definere omfanget av modulens konfigurasjon. Så det jeg gjør for øyeblikket er å tukle med Nest sine instanser for å injisere omfanget i den, noe jeg tror ikke er det beste å gjøre.

Her er kodeeksemplet jeg laget for problemet:

Bibliotekkode

// decorator
export function Configurable(scope: string) {
  return (target: object, key: string | symbol, index?: number) => {
    const meta = Reflect.getMetadata(CONFIGURABLE_METADATA, target) || {};
    let dependencies = meta.dependencies || [];

    dependencies = [...dependencies, { scope, key }];

    Reflect.defineMetadata(
      CONFIGURABLE_METADATA,
      { dependencies },
      target,
    );

    Inject(CONFIGURATION_PROVIDER_TOKEN)(target, key, index);
  };
}
// explorer service
@Injectable()
export class ExplorerService {
  constructor(private readonly modulesContainer: ModulesContainer) {}

  injectScopes(): void {
    const providers = [...this.modulesContainer.values()]
      .map((module: NestModule) => {
        return [...module.providers.values()];
      }).reduce((a, b) => a.concat(b), []);

    providers.forEach(provider => {
      const { instance } = provider;

      if (!instance && !instance.constructor) {
        return;
      }

      // custom metadata
      const meta = Reflect.getMetadata(CONFIGURABLE_METADATA, instance.constructor);

      if (meta) {
        meta.dependencies.forEach(dep => {
          const { index, scope } = dep;
          const wrapper = provider[INSTANCE_METADATA_SYMBOL].dependencies[index];
          const { instance: depInstance } = wrapper;
          Object.defineProperty(depInstance, 'scope', { value: scope });
        });
      }
    });
  }
}

Applikasjonskode (ved bruk av biblioteket)

// usage in the application
@Module({
  imports: [ConfigurationModule.forRoot(factoryOptions)],
  providers: [UserConfigProvider],
  exports: [ConfigurationModule]
})
export class AppModule {}
// user config provider
@Injectable()
export class AssessmentConfiguration {
  constructor(
    @Configurable('common')
    private readonly commonConfig: ConfigurationService,
    @Configurable('users')
    private readonly usersConfig: ConfigurationService,
  ) {}
}

Setter pris på all hjelp jeg kan få eller all diskusjon vi kan generere ut fra dette. Hvis det mangler noe, kan jeg gi mer informasjon eller kontekst.

Relaterte artikler