Есть ли способ избежать предварительного объявления токена инъекции, который будет объявлен в других модулях? - PullRequest
0 голосов
/ 06 апреля 2020

Я создаю EventPublisher, который должен принимать 3 зависимости в конструкторе

Издатель, требующий зависимостей


@Injectable()
export class EventStorePublisher implements IEventPublisher {
    constructor(private readonly eventStore: IEventStore,
                @Inject('STREAM_NAME_PUBLISHER') private readonly category: string,
                @Inject('ID_ATTRIBUTE_NAME_PUBLISHER') private readonly idName: string) {
    }
}

Таким образом, я хочу настроить публикацию.

Это часть утилитного модуля, который на данный момент не знает, какая строка введена внутри:

Util module

@Global()
@Module({
    providers: [
        {
            provide: IEventStore,
            useClass: EventStore,
        },
//...
    ],
    exports: [
        {
            provide: IEventStore,
            useClass: EventStore,
        },
//...
    ],
})
export class EventStoreModule {
//...

    static forFeature(): DynamicModule {
        return {
            module: EventStoreModule,
            providers: [
                EventStorePublisher,
                {
                    provide: "STREAM_NAME_PUBLISHER",
                    useValue: null
                },
                {
                    provide: "ID_ATTRIBUTE_NAME_PUBLISHER",
                    useValue: null
                },
            ],
            exports: [
                EventStorePublisher,
                {
                    provide: "STREAM_NAME_PUBLISHER",
                    useValue: null
                },
                {
                    provide: "ID_ATTRIBUTE_NAME_PUBLISHER",
                    useValue: null
                },

            ],
        };
    }
}

Я не нашел другого способа предотвратить Nest JS выдать ошибку об отсутствующих определениях токенов STREAM_NAME_PUBLISHER или ID_ATTRIBUTE_NAME_PUBLISHER. Я вынужден предоставить их и экспортировать, в противном случае модуль не будет работать.

Когда дело доходит до модуля, которому необходимо настроить категорию, и idName:

Последний модуль, который будет настроить мои токены

@Module({
    imports: [
        CqrsModule,
        EventStoreModule.forFeature(),
        EventStorePublisher,
    ],
    providers: [
        //...
        {
            provide: "STREAM_NAME_PUBLISHER",
            useValue: "person"
        },
        {
            provide: "ID_ATTRIBUTE_NAME_PUBLISHER",
            useValue: "personId"
        },
        {
            provide: EventStorePublisher,
            useFactory: (eventStore:IEventStore,category: string, id: string) => new EventStorePublisher(eventStore, category,id),
            inject: [IEventStore, "STREAM_NAME_PUBLISHER", "ID_ATTRIBUTE_NAME_PUBLISHER"]
        },

    ],
    controllers: [
        //...
    ],
})
export class PersonModule implements OnModuleInit {
//...
}

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

1 Ответ

1 голос
/ 07 апреля 2020

Я реализовал нечто похожее на это, но в целом, это определенно довольно грязно. Для моего кода я реализовал подход типа NoopService, где код минимально возможен и ничего не делает, кроме как позволяет вещам пройти. Все мои провайдеры, которые должны были быть перезаписаны, были инициализированы с

{
  provide: ProviderName,
  useClass: NoopService,
}

, чтобы я мог просто позволить провайдерам должным образом инициализироваться, не беспокоясь о каком-либо коде, проходящем через них. Это также привело к необходимости проверок кода, так как я бы не хотел, чтобы эти 1005 действительно что-то делали. Если вы хотите проверить , кодовая база находится здесь , в частности, в файлах ogma-core.module.ts, ogma.providers.ts и interceptor/ogma.intereptor.ts (вместе с теми, которые вы можете отслеживать оттуда).

...