From 7cb6d145db6f50d1a5c7fa5e3363aa7e00186116 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Mon, 9 Dec 2024 09:44:57 +0100 Subject: [PATCH] backend-app-api: fix handling of multiton factories from feature loaders Signed-off-by: Patrik Oldsberg --- .../src/wiring/BackendInitializer.test.ts | 42 +++++++++++++++++++ .../src/wiring/BackendInitializer.ts | 2 +- .../src/wiring/ServiceRegistry.ts | 3 -- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts index 5e98a71d46..86b0b51bd9 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.test.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.test.ts @@ -215,6 +215,48 @@ describe('BackendInitializer', () => { expect(factory3).not.toHaveBeenCalled(); }); + it('should include all multiton service factories', async () => { + expect.assertions(5); + + const ref = createServiceRef({ id: '1', multiton: true }); + const factory1 = mkNoopFactory(ref).mockResolvedValue(1); + const factory2 = mkNoopFactory(ref).mockResolvedValue(2); + const factory3 = mkNoopFactory(ref).mockResolvedValue(3); + const factory4 = mkNoopFactory(ref).mockResolvedValue(4); + + const init = new BackendInitializer([...baseFactories, factory1]); + init.add(factory2); + init.add( + createBackendFeatureLoader({ + deps: {}, + *loader() { + yield factory3; + yield factory4; + }, + }), + ); + init.add( + createBackendPlugin({ + pluginId: 'tester', + register(reg) { + reg.registerInit({ + deps: { ns: ref }, + async init({ ns }) { + expect(ns).toEqual([1, 2, 3, 4]); + }, + }); + }, + }), + ); + + await init.start(); + + expect(factory1).toHaveBeenCalled(); + expect(factory2).toHaveBeenCalled(); + expect(factory3).toHaveBeenCalled(); + expect(factory4).toHaveBeenCalled(); + }); + // Note: this is an important escape hatch in case to loaders conflict and you need to select the winning service factory it('should allow duplicate service from feature loaders if overridden', async () => { const ref = createServiceRef<{}>({ id: '1' }); diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index 89e07ac405..440a334d9b 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -576,7 +576,7 @@ export class BackendInitializer { // // If a factory has already been explicitly installed, the service // factory provided by the loader will simply be ignored. - if (isServiceFactory(feature)) { + if (isServiceFactory(feature) && !feature.service.multiton) { const conflictingLoader = servicesAddedByLoaders.get( feature.service.id, ); diff --git a/packages/backend-app-api/src/wiring/ServiceRegistry.ts b/packages/backend-app-api/src/wiring/ServiceRegistry.ts index 162c175615..90b108206e 100644 --- a/packages/backend-app-api/src/wiring/ServiceRegistry.ts +++ b/packages/backend-app-api/src/wiring/ServiceRegistry.ts @@ -195,9 +195,6 @@ export class ServiceRegistry { if (ref.id === coreServices.pluginMetadata.id) { return true; } - if (ref.multiton) { - return false; - } return this.#addedFactoryIds.has(ref.id); }