У меня есть общая библиотека, которая будет предоставлять модули для других приложений.Поэтому мне нужны динамические настраиваемые параметры для создания пользовательских экземпляров для каждого модуля внутри приложения.
Я уже открыл эту проблему в официальном репозитории 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,
) {}
}
Оцените любойпомощь, которую я могу получить, или любое обсуждение, которое мы можем получить из этого.Если чего-то не хватает, я могу предоставить больше информации или контекста.