Есть ли способ передать пользовательские параметры для использования Factory DynamicModules в NestJs? - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть общая библиотека, которая будет предоставлять модули для других приложений.Поэтому мне нужны динамические настраиваемые параметры для создания пользовательских экземпляров для каждого модуля внутри приложения.

Я уже открыл эту проблему в официальном репозитории nestjs / tasks / 1965 , но, возможно, кто-то здесьможет дать мне некоторые идеи или помочь мне с этим.

Я уже просмотрел документацию nestjs, а также прочитал код и вопросы, но не могу найти способ динамического получения параметров из процесса создания для генерациипользовательские экземпляры того, что я когда-либо хочу.

Поэтому в основном мне нужно предоставить строку, которая может войти в процесс создания экземпляра, поэтому возвращаемый экземпляр будет использовать эту строку для определения конфигурации модуля.Итак, в настоящее время я взламываю экземпляры Nest, чтобы внедрить в них область видимости, что я считаю не лучшим решением.

Вот пример кода, который я сделал для этой проблемы:

Код библиотеки

// 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 });
        });
      }
    });
  }
}

Код приложения (с использованием библиотеки)

// 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,
  ) {}
}

Оцените любойпомощь, которую я могу получить, или любое обсуждение, которое мы можем получить из этого.Если чего-то не хватает, я могу предоставить больше информации или контекста.

...