From 6b12b661300d5b792b97ffcb039a3f4be8342907 Mon Sep 17 00:00:00 2001 From: RWOverdijk Date: Sat, 22 Sep 2018 20:27:58 +0200 Subject: [PATCH] feat(ServiceManager): fix typings and add support for shareable services --- .../ServiceManager/FactoryInterface.ts | 2 +- src/Library/ServiceManager/ServiceManager.ts | 28 ++++++++++++++----- .../ServiceManagerConfigInterface.ts | 10 +++---- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/Library/ServiceManager/FactoryInterface.ts b/src/Library/ServiceManager/FactoryInterface.ts index ad356fa..078cc29 100644 --- a/src/Library/ServiceManager/FactoryInterface.ts +++ b/src/Library/ServiceManager/FactoryInterface.ts @@ -1,2 +1,2 @@ -export interface FactoryInterface { +export interface FactoryInterface extends Function { } diff --git a/src/Library/ServiceManager/ServiceManager.ts b/src/Library/ServiceManager/ServiceManager.ts index fb8055d..20d3a5d 100644 --- a/src/Library/ServiceManager/ServiceManager.ts +++ b/src/Library/ServiceManager/ServiceManager.ts @@ -1,6 +1,7 @@ import { ServiceManagerInterface } from './ServiceManagerInterface'; -import { ServicesMapType, FactoriesMapType, AliasesType, ServiceKeyType, ServiceFactoryType, SharedMapType, ServiceManagerConfigType, ServiceType } from './ServiceManagerConfigInterface'; +import { ServicesMapType, FactoriesMapType, AliasesType, ServiceKeyType, ServiceFactoryType, SharedMapType, ServiceManagerConfigType } from './ServiceManagerConfigInterface'; import { NotFoundError } from '../Error'; +import { Instantiable } from '../Core/Types'; /** * @export @@ -29,7 +30,7 @@ export class ServiceManager implements ServiceManagerInterface { } public get(Service: ServiceKeyType, forceTransient: boolean = false): T { - const resolvedName = this.resolveName(Service) as ServiceType; + const resolvedName = this.resolveName(Service) as ServiceKeyType; if (!this.has(resolvedName)) { throw new NotFoundError(`Unable to locate service "${typeof Service === 'string' ? Service : Service.name}".`); @@ -37,9 +38,10 @@ export class ServiceManager implements ServiceManagerInterface { if (forceTransient || !this.services.has(resolvedName)) { const service = this.factories.get(resolvedName)(this.creationContext) as T; + const shared = this.shared.has(resolvedName) ? this.shared.get(resolvedName) : this.sharedByDefault; // We just needed a new instance or we don't want our instances to be shared.. Return service. - if (forceTransient || (!this.sharedByDefault && !this.shared.has(resolvedName))) { + if (forceTransient || !shared) { return service; } @@ -50,7 +52,7 @@ export class ServiceManager implements ServiceManagerInterface { } has(Service: ServiceKeyType): boolean { - const resolvedName = this.resolveName(Service) as ServiceType; + const resolvedName = this.resolveName(Service) as ServiceKeyType; return this.services.has(resolvedName) || this.factories.has(resolvedName); } @@ -81,15 +83,15 @@ export class ServiceManager implements ServiceManagerInterface { } if (config.shared instanceof Map) { - config.shared.forEach((value, key: Function | string) => this.shared.set(key, value)); + config.shared.forEach((value, key: ServiceKeyType) => this.shared.set(key, value)); } if (config.services instanceof Map) { - config.services.forEach((value, key: Function | string) => this.services.set(key, value)); + config.services.forEach((value, key: ServiceKeyType) => this.services.set(key, value)); } if (config.invokables instanceof Map) { - config.invokables.forEach((value, key: Function | string) => { + config.invokables.forEach((value: Instantiable, key: ServiceKeyType) => { this.factories.set(key, () => new value); }); } @@ -105,6 +107,18 @@ export class ServiceManager implements ServiceManagerInterface { return this; } + public registerAliases(aliases: AliasesType): this { + Object.assign(this.aliases, aliases); + + return this; + } + + public registerAlias(alias: string, to: string | Function): this { + this.aliases[alias] = to; + + return this; + } + private resolveName(name: ServiceKeyType): ServiceKeyType { if (typeof name !== 'string') { return name; diff --git a/src/Library/ServiceManager/ServiceManagerConfigInterface.ts b/src/Library/ServiceManager/ServiceManagerConfigInterface.ts index cc24d8c..00f0965 100644 --- a/src/Library/ServiceManager/ServiceManagerConfigInterface.ts +++ b/src/Library/ServiceManager/ServiceManagerConfigInterface.ts @@ -1,20 +1,20 @@ import { ServiceManagerInterface } from './ServiceManagerInterface'; - -export interface ServiceType extends Function { new (...args: any[]): T; } +import { Instantiable } from '../Core/Types'; +import { FactoryInterface } from './FactoryInterface'; export interface ServiceFactoryType extends Function { (sm?: ServiceManagerInterface): T; } -export type FactoriesMapType = Map>; +export type FactoriesMapType = Map; export type ServicesMapType = Map; -export type InvokablesMapType = Map; +export type InvokablesMapType = Map | string, Instantiable>; export type AliasesType = { [alias: string]: string | Function }; export type SharedMapType = Map; -export type ServiceKeyType = ServiceType | string; +export type ServiceKeyType = Instantiable | string; export type ServiceManagerConfigType = Partial<{ sharedByDefault: boolean;