From b983322e0ee1e2b66c142e98ccb6ef3b68490b87 Mon Sep 17 00:00:00 2001 From: Victor Mendele Date: Wed, 6 Oct 2021 12:09:08 +0200 Subject: [PATCH] add allowServiceOverriding --- .../container/src/Implementation/Container.ts | 12 ++++++----- packages/container/tests/Container.spec.ts | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/container/src/Implementation/Container.ts b/packages/container/src/Implementation/Container.ts index 8d3acb9..446b6aa 100644 --- a/packages/container/src/Implementation/Container.ts +++ b/packages/container/src/Implementation/Container.ts @@ -86,18 +86,20 @@ class ContainerBuilder implements ContainerBuilderInterface { .set(LifeCycle.Singleton, new Map()) .set(LifeCycle.Transient, new Map()) + private readonly allowServiceOverriding: boolean + constructor(options: CreateContainerBuilderOptions, private readonly createProvider: (containerInterface: ContainerInterface) => SyncServiceProviderInterface = createSyncServiceProvider, private readonly createAsyncProvider: (containerInterface: ContainerInterface) => AsyncServiceProviderInterface = createAsyncServiceProvider ) { - options.loaders.forEach(loader => loader(this)) + options.loaders?.forEach(loader => loader(this)) + this.allowServiceOverriding = options.allowServiceOverriding ?? false } addFactory(key: ServiceKey, factory: SyncServiceFactory, lifeCycle: LifeCycle): this { - if (this.isAlreadyRegistered(key)) + if (this.isAlreadyRegistered(key) && !this.allowServiceOverriding) throw new ServiceAlreadyRegisteredError(key) - this.syncFactories.get(lifeCycle)?.set(key, factory) // this.syncFactories.set(key, {factory, lifeCycle}) return this @@ -120,7 +122,7 @@ class ContainerBuilder implements ContainerBuilderInterface { } addAsyncFactory(key: ServiceKey, factory: AsyncServiceFactory>, lifeCycle: LifeCycle): this { - if (this.isAlreadyRegistered(key)) + if (this.isAlreadyRegistered(key) && !this.allowServiceOverriding) throw new ServiceAlreadyRegisteredError(key) this.asyncFactories.get(lifeCycle)?.set(key, factory) @@ -136,7 +138,7 @@ class ContainerBuilder implements ContainerBuilderInterface { } } -export type CreateContainerBuilderOptions = { loaders: ServiceLoaderInterface[] } +export type CreateContainerBuilderOptions = { loaders?: ServiceLoaderInterface[], allowServiceOverriding?: boolean } const defaultOptions = { loaders: [] } export const createContainerBuilder = (options: CreateContainerBuilderOptions = defaultOptions, diff --git a/packages/container/tests/Container.spec.ts b/packages/container/tests/Container.spec.ts index afbe3a5..8fbbd59 100644 --- a/packages/container/tests/Container.spec.ts +++ b/packages/container/tests/Container.spec.ts @@ -153,6 +153,26 @@ it('should throw when overriding service', function () { expect(shouldThrow4).toThrow(`Service with key "MyService" was already registered.`) }) +it('should not throw when overriding service if the allowServiceOverriding is true', async () => { + // Arrange + const builder = createContainerBuilder({ allowServiceOverriding: true }) + + // Act + const container = builder + .addFactory('MyService', () => 'hello', LifeCycle.Singleton) + .addFactory('MyService', () => 'world', LifeCycle.Singleton) + .addAsyncFactory('MyAsyncService', async () => 'hello', LifeCycle.Singleton) + .addAsyncFactory('MyAsyncService', async () => 'world', LifeCycle.Singleton) + .build() + + const myService = container.get('MyService') + const myServiceAsync = await container.getAsync('MyAsyncService') + + // Assert + expect(myService).toBe('world') + expect(myServiceAsync).toBe('world') +}) + describe('services lifetime', function () { it('should create singleton services', function () {