ing
This commit is contained in:
parent
6a9cc22a06
commit
c5358742ce
|
@ -15,7 +15,7 @@ const Configuration = (qualifier?: string | symbol ) => createDecorator('Configu
|
|||
throw new Error('Cannot apply @Injectable or @Injectable stereotype decorator multiple times.');
|
||||
}
|
||||
|
||||
configurationDefinition = getConfigurationDefinition(target, true);
|
||||
configurationDefinition = getConfigurationDefinition(target.prototype, true);
|
||||
configurationDefinition.Stereotype = InjectableSterotype.CONFIGURATION;
|
||||
configurationDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { ClassType, PropertyType } from '@loafer/core/constants';
|
||||
|
||||
interface PouchConfig {
|
||||
qualifier?: string | symbol;
|
||||
type?: any;
|
||||
qualifier?: PropertyType;
|
||||
type?: ClassType;
|
||||
}
|
||||
|
||||
export default PouchConfig;
|
||||
|
|
|
@ -15,7 +15,7 @@ const Service = (qualifier?: string | symbol ) => createDecorator('Service', {
|
|||
throw new Error('Cannot apply @Injectable or @Injectable stereotype decorator multiple times.');
|
||||
}
|
||||
|
||||
injectableDefinition = getInjectableDefinition(target, true);
|
||||
injectableDefinition = getInjectableDefinition(target.prototype, true);
|
||||
injectableDefinition.Stereotype = InjectableSterotype.SERVICE;
|
||||
injectableDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import { DESIGN_RETURNTYPE } from '@loafer/core/constants';
|
||||
import { ClassType, DESIGN_RETURNTYPE, PropertyType } from '@loafer/core/constants';
|
||||
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
|
||||
import PouchConfig from '@loafer/context/decorator/PouchConfig';
|
||||
|
||||
class ConfigurationDefinition extends InjectableDefinition {
|
||||
protected _qualifier: string | symbol = undefined;
|
||||
protected _qualifier: PropertyType = undefined;
|
||||
protected _pouchMap: Map<string, PouchConfig>;
|
||||
|
||||
public constructor(type: Object) {
|
||||
super(type);
|
||||
public constructor(clazz: ClassType) {
|
||||
super(clazz);
|
||||
}
|
||||
|
||||
public addPouch(propertyKey: string, pouchConfig: PouchConfig): void {
|
||||
if (undefined === this._pouchMap) {
|
||||
this._pouchMap = new Map();
|
||||
}
|
||||
let returnType: any = Reflect.getMetadata(DESIGN_RETURNTYPE, this._type, propertyKey);
|
||||
let returnType: any = Reflect.getMetadata(DESIGN_RETURNTYPE, this._clazz, propertyKey);
|
||||
|
||||
if (undefined === pouchConfig.type) {
|
||||
pouchConfig.type = returnType;
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
import { ClassType, PropertyType } from '@loafer/core/constants';
|
||||
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
|
||||
import { InjectableSterotype, PouchScope } from '@loafer/pouches/constants';
|
||||
|
||||
class InjectableDefinition implements PouchDefinition {
|
||||
protected _type: Object;
|
||||
protected _clazz: ClassType;
|
||||
protected _stereotype: InjectableSterotype;
|
||||
protected _scope: PouchScope = PouchScope.SINGLETON;
|
||||
protected _qualifier: string | symbol = undefined;
|
||||
protected _qualifier: PropertyType = undefined;
|
||||
protected _postConstruct: Set<string> = undefined;
|
||||
protected _preDestroy: Set<string> = undefined;
|
||||
|
||||
public constructor(type: Object) {
|
||||
this._type = type;
|
||||
public constructor(clazz: ClassType) {
|
||||
this._clazz = clazz;
|
||||
this._stereotype = InjectableSterotype.INJECTABLE;
|
||||
}
|
||||
|
||||
public get Type(): Object {
|
||||
return this._type;
|
||||
public get Clazz(): ClassType {
|
||||
return this._clazz;
|
||||
}
|
||||
|
||||
public get Stereotype(): InjectableSterotype {
|
||||
|
@ -34,11 +35,11 @@ class InjectableDefinition implements PouchDefinition {
|
|||
this._scope = scope;
|
||||
}
|
||||
|
||||
public get Qualifier(): string | symbol {
|
||||
public get Qualifier(): PropertyType {
|
||||
return this._qualifier;
|
||||
}
|
||||
|
||||
public set Qualifier(qualifier: string | symbol) {
|
||||
public set Qualifier(qualifier: PropertyType) {
|
||||
this._qualifier = qualifier;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
Construtorable,
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
import AppContext from '@loafer/context/AppContext';
|
||||
|
@ -17,12 +18,11 @@ class DefaultAppContext implements AppContext {
|
|||
return this.pouchFactory;
|
||||
}
|
||||
|
||||
public getPouch<T>(type: Construtorable<T>, ...args: any[]): T {
|
||||
return this.pouchFactory.getPouch(type, args);
|
||||
public getPouch(qualifier: PropertyType, clazz: ClassType, ...args: any[]): any {
|
||||
return this.pouchFactory.getPouch(qualifier, clazz, args);
|
||||
}
|
||||
|
||||
public getPouchByQualifier<T>(type: Construtorable<T>, qualifier: string | symbol, ...args: any[]): T {
|
||||
return this.pouchFactory.getPouchByQualifier(type, qualifier, args);
|
||||
public getPouchByType(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any {
|
||||
return this.pouchFactory.getPouchByType(clazz, qualifier, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { ClassType } from '@loafer/core/constants';
|
||||
import getClassMetadata from '@loafer/core/util/metadata/getClassMetadata';
|
||||
import { CONTEXT_INJECTABLE_DEFINITION } from '@loafer/context/constants';
|
||||
import ConfigurationDefinition from '@loafer/context/definition/ConfigurationDefinition';
|
||||
|
||||
export const getConfigurationDefinition = (target: Object, isCreate: boolean = false) =>
|
||||
getClassMetadata(target, CONTEXT_INJECTABLE_DEFINITION, ConfigurationDefinition, isCreate);
|
||||
export const getConfigurationDefinition = (clazz: ClassType, isCreate: boolean = false) =>
|
||||
getClassMetadata(clazz, CONTEXT_INJECTABLE_DEFINITION, ConfigurationDefinition, isCreate);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { ClassType } from '@loafer/core/constants';
|
||||
import getClassMetadata from '@loafer/core/util/metadata/getClassMetadata';
|
||||
import { CONTEXT_INJECTABLE_DEFINITION } from '@loafer/context/constants';
|
||||
import InjectableDefinition from '@loafer/context/definition/InjectableDefinition';
|
||||
|
||||
export const getInjectableDefinition = (target: Object, isCreate: boolean = false) =>
|
||||
getClassMetadata(target, CONTEXT_INJECTABLE_DEFINITION, InjectableDefinition, isCreate);
|
||||
export const getInjectableDefinition = (clazz: ClassType, isCreate: boolean = false) =>
|
||||
getClassMetadata(clazz, CONTEXT_INJECTABLE_DEFINITION, InjectableDefinition, isCreate);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export type Construtorable<T> = {new(...args: any[]): T};
|
||||
export type ClassType = Object;
|
||||
export type PropertyType = string | symbol;
|
||||
|
||||
export enum DecoratorType {
|
||||
CLASS,
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
export type MetadataDefinable<T> = {new(target: Function): T};
|
||||
import {
|
||||
ClassType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
const getClassMetadata = <DefinitionType>(target: Object,
|
||||
export type MetadataDefinable<T> = {new(clazz: ClassType): T};
|
||||
|
||||
const getClassMetadata = <DefinitionType>(clazz: ClassType,
|
||||
metadataKey: any,
|
||||
definitionType: MetadataDefinable<DefinitionType>,
|
||||
isCreate: boolean = false): DefinitionType => {
|
||||
|
||||
let definition: DefinitionType;
|
||||
if (Reflect.hasOwnMetadata(metadataKey, target) !== true) {
|
||||
if (Reflect.hasOwnMetadata(metadataKey, clazz) !== true) {
|
||||
if (!isCreate) {
|
||||
return undefined;
|
||||
}
|
||||
definition = Object.create(definitionType.prototype);
|
||||
definition.constructor.call(definition, target);
|
||||
definition.constructor.call(definition, clazz);
|
||||
|
||||
Reflect.defineMetadata(metadataKey, definition, target);
|
||||
Reflect.defineMetadata(metadataKey, definition, clazz);
|
||||
} else {
|
||||
definition = Reflect.getMetadata(metadataKey, target);
|
||||
definition = Reflect.getMetadata(metadataKey, clazz);
|
||||
}
|
||||
return definition;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { ClassType, PropertyType } from '@loafer/core/constants';
|
||||
|
||||
interface InjectConfig {
|
||||
qualifier?: string | symbol;
|
||||
qualifier?: PropertyType;
|
||||
required?: boolean;
|
||||
type?: any;
|
||||
clazz?: ClassType;
|
||||
}
|
||||
|
||||
export default InjectConfig;
|
||||
|
|
|
@ -1,33 +1,39 @@
|
|||
import {
|
||||
ClassType,
|
||||
DecoratorType,
|
||||
DESIGN_PARAMTYPES,
|
||||
DESIGN_TYPE,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
import { InjectSterotype } from '@loafer/pouches/constants';
|
||||
import { validateQualifier } from '@loafer/pouches/util/qualifier';
|
||||
import InjectConfig from '@loafer/pouches/decorator/InjectConfig';
|
||||
import * as CoreConstants from '@loafer/core/constants';
|
||||
|
||||
export interface InjectItem {
|
||||
stereotype: InjectSterotype;
|
||||
decoratorType: CoreConstants.DecoratorType;
|
||||
decoratorType: DecoratorType;
|
||||
propertyConfig?: InjectConfig;
|
||||
parameterConfigMap?: Map<number, InjectConfig>;
|
||||
}
|
||||
|
||||
class InjectDefinition {
|
||||
protected target: Object;
|
||||
protected injectMap: Map<string | symbol, InjectItem>;
|
||||
protected clazz: ClassType;
|
||||
protected injectMap: Map<PropertyType, InjectItem>;
|
||||
|
||||
public constructor(target: Object) {
|
||||
this.target = target;
|
||||
public constructor(clazz: ClassType) {
|
||||
this.clazz = clazz;
|
||||
this.injectMap = new Map();
|
||||
}
|
||||
|
||||
public get injectors(): Map<string | symbol, InjectItem> {
|
||||
public get injectors(): Map<PropertyType, InjectItem> {
|
||||
return this.injectMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* addInject
|
||||
*/
|
||||
public addInject(injectConfig: InjectConfig, propertyKey: string | symbol, parameterIndex?: number): void {
|
||||
injectConfig.qualifier = validateQualifier(this.target, injectConfig.qualifier);
|
||||
public addInject(injectConfig: InjectConfig, propertyKey: PropertyType, parameterIndex?: number): void {
|
||||
injectConfig.qualifier = validateQualifier(this.clazz, injectConfig.qualifier);
|
||||
if (undefined === injectConfig.required) {
|
||||
injectConfig.required = false;
|
||||
}
|
||||
|
@ -42,7 +48,7 @@ class InjectDefinition {
|
|||
/**
|
||||
* addValue
|
||||
*/
|
||||
public addValue(value: string, propertyKey: string | symbol, parameterIndex?: number): void {
|
||||
public addValue(value: string, propertyKey: PropertyType, parameterIndex?: number): void {
|
||||
if(typeof parameterIndex === 'number') {
|
||||
this.addValueParameter(value, propertyKey, parameterIndex);
|
||||
} else {
|
||||
|
@ -50,22 +56,22 @@ class InjectDefinition {
|
|||
}
|
||||
}
|
||||
|
||||
private addValueProperty(value: string, propertyKey: string | symbol): void {
|
||||
private addValueProperty(value: string, propertyKey: PropertyType): void {
|
||||
return;
|
||||
}
|
||||
private addValueParameter(value: string, propertyKey: string | symbol, parameterIndex: number): void {
|
||||
private addValueParameter(value: string, propertyKey: PropertyType, parameterIndex: number): void {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private addInjectParameter(injectConfig: InjectConfig,
|
||||
propertyKey: string | symbol, parameterIndex: number): void {
|
||||
propertyKey: PropertyType, parameterIndex: number): void {
|
||||
let injectItem: InjectItem;
|
||||
let parameterTypes: any[] = Reflect.getMetadata(CoreConstants.DESIGN_PARAMTYPES, this.target, propertyKey);
|
||||
let parameterTypes: any[] = Reflect.getMetadata(DESIGN_PARAMTYPES, this.clazz, propertyKey);
|
||||
|
||||
if (undefined === injectConfig.type) {
|
||||
injectConfig.type = parameterTypes[parameterIndex];
|
||||
if (undefined === injectConfig.clazz) {
|
||||
injectConfig.clazz = parameterTypes[parameterIndex];
|
||||
}
|
||||
|
||||
if (this.injectMap.has(propertyKey)) {
|
||||
|
@ -73,7 +79,7 @@ class InjectDefinition {
|
|||
} else {
|
||||
injectItem = {
|
||||
stereotype: InjectSterotype.INJECT,
|
||||
decoratorType: CoreConstants.DecoratorType.PARAMETER,
|
||||
decoratorType: DecoratorType.PARAMETER,
|
||||
};
|
||||
this.injectMap.set(propertyKey, injectItem);
|
||||
}
|
||||
|
@ -90,20 +96,20 @@ class InjectDefinition {
|
|||
|
||||
}
|
||||
|
||||
private addInjectProperty(injectConfig: InjectConfig, propertyKey: string | symbol): void {
|
||||
private addInjectProperty(injectConfig: InjectConfig, propertyKey: PropertyType): void {
|
||||
if (this.injectMap.has(propertyKey)) {
|
||||
throw new Error(`Cannot apply @inject decorator on one property[${propertyKey}] multiple times.`);
|
||||
}
|
||||
|
||||
let propertyType: any = Reflect.getMetadata(CoreConstants.DESIGN_TYPE, this.target, propertyKey);
|
||||
let propertyType: any = Reflect.getMetadata(DESIGN_TYPE, this.clazz, propertyKey);
|
||||
|
||||
if (undefined === injectConfig.type) {
|
||||
injectConfig.type = propertyType;
|
||||
if (undefined === injectConfig.clazz) {
|
||||
injectConfig.clazz = propertyType;
|
||||
}
|
||||
|
||||
let injectItem: InjectItem = {
|
||||
stereotype: InjectSterotype.INJECT,
|
||||
decoratorType: CoreConstants.DecoratorType.PROPERTY,
|
||||
decoratorType: DecoratorType.PROPERTY,
|
||||
propertyConfig: injectConfig,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,8 +1,23 @@
|
|||
import { Construtorable } from '@loafer/core/constants';
|
||||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
interface PouchFactory {
|
||||
getPouch<T>(type: Construtorable<T>, ...args: any[]): T;
|
||||
getPouchByQualifier<T>(type: Construtorable<T>, qualifier: string | symbol, ...args: any[]): T;
|
||||
/**
|
||||
* @param qualifier is identity of pouch
|
||||
* @param clazz is type of pouch (if clazz is not specified, set the undefined)
|
||||
* @param args are argument of target constructor
|
||||
* @returns an instance of pouch
|
||||
*/
|
||||
getPouch(qualifier: PropertyType, clazz: ClassType, ...args: any[]): any;
|
||||
/**
|
||||
* @param clazz is type of pouch
|
||||
* @param qualifier is identity of pouch (if qualifier is not specified, set the undefined)
|
||||
* @param args are argument of target constructor
|
||||
* @returns an instance of pouch
|
||||
*/
|
||||
getPouchByType(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { ClassType, PropertyType } from '@loafer/core/constants';
|
||||
import { InjectableSterotype, PouchScope } from '@loafer/pouches/constants';
|
||||
|
||||
interface PouchDefinition {
|
||||
readonly Type: Object;
|
||||
readonly Clazz: ClassType;
|
||||
Stereotype: InjectableSterotype;
|
||||
Scope: PouchScope;
|
||||
Qualifier: string | symbol;
|
||||
Qualifier: PropertyType;
|
||||
readonly PostConstruct: Set<string>;
|
||||
readonly PreDestroy: Set<string>;
|
||||
addPostConstruct(postConstruct: string): void;
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import {
|
||||
Construtorable,
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
interface SingletonPouchRegistry {
|
||||
registerSingleton(pouch: any, qualifier?: string | symbol): void;
|
||||
getSingleton<T>(type: Construtorable<T>, qualifier?: string | symbol): T;
|
||||
hasSingleton<T>(type: Construtorable<T>, qualifier?: string | symbol): boolean;
|
||||
registerSingleton(pouch: any, qualifier?: PropertyType): void;
|
||||
getSingleton(qualifier: PropertyType, clazz?: ClassType): any;
|
||||
getSingletonByClass(clazz: ClassType, qualifier?: PropertyType): any;
|
||||
hasSingleton(qualifier: PropertyType, clazz?: ClassType): boolean;
|
||||
hasSingletonByClass(clazz: ClassType, qualifier?: PropertyType): boolean;
|
||||
}
|
||||
|
||||
export default SingletonPouchRegistry;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
import {
|
||||
validateQualifier,
|
||||
} from '@loafer/pouches/util/qualifier';
|
||||
|
@ -9,46 +14,46 @@ import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/implement/Def
|
|||
|
||||
|
||||
abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implements PouchDefinitionRegistry {
|
||||
protected pouchDefinitionMap: Map<string | symbol, Map<Object, PouchDefinition>>;
|
||||
protected pouchDefinitionMap: Map<PropertyType, Map<ClassType, PouchDefinition>>;
|
||||
public constructor() {
|
||||
super();
|
||||
this.pouchDefinitionMap = new Map();
|
||||
}
|
||||
|
||||
public registerPouchDefinition(pouchDefinition: PouchDefinition): void {
|
||||
let type = pouchDefinition.Type;
|
||||
let qualifier = validateQualifier(type, pouchDefinition.Qualifier);
|
||||
let clazz = pouchDefinition.Clazz;
|
||||
let qualifier = validateQualifier(clazz, pouchDefinition.Qualifier);
|
||||
|
||||
if (this.hasPouchDefinition(type, qualifier)) {
|
||||
throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is exist already`);
|
||||
if (this.hasPouchDefinition(clazz, qualifier)) {
|
||||
throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is exist already`);
|
||||
}
|
||||
let map = this.pouchDefinitionMap.get(qualifier);
|
||||
if (undefined === map) {
|
||||
map = new Map();
|
||||
this.pouchDefinitionMap.set(qualifier, map);
|
||||
}
|
||||
map.set(type, pouchDefinition);
|
||||
map.set(clazz, pouchDefinition);
|
||||
}
|
||||
public removePouchDefinition(type: Object, qualifier?: string | symbol): void {
|
||||
const _qualifier = validateQualifier(type, qualifier);
|
||||
if (!this.hasPouchDefinition(type, _qualifier)) {
|
||||
throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is not exist`);
|
||||
public removePouchDefinition(clazz: ClassType, qualifier?: PropertyType): void {
|
||||
const _qualifier = validateQualifier(clazz, qualifier);
|
||||
if (!this.hasPouchDefinition(clazz, _qualifier)) {
|
||||
throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is not exist`);
|
||||
}
|
||||
this.pouchDefinitionMap.get(_qualifier).delete(type);
|
||||
this.pouchDefinitionMap.get(_qualifier).delete(clazz);
|
||||
if (0 === this.pouchDefinitionMap.get(_qualifier).size) {
|
||||
this.pouchDefinitionMap.delete(_qualifier);
|
||||
}
|
||||
}
|
||||
public getPouchDefinition(type: Object, qualifier?: string | symbol): PouchDefinition {
|
||||
const _qualifier = validateQualifier(type, qualifier);
|
||||
public getPouchDefinition(clazz: ClassType, qualifier?: PropertyType): PouchDefinition {
|
||||
const _qualifier = validateQualifier(clazz, qualifier);
|
||||
|
||||
if (!this.pouchDefinitionMap.has(_qualifier)) {
|
||||
return undefined;
|
||||
}
|
||||
return this.pouchDefinitionMap.get(_qualifier).get(type);
|
||||
return this.pouchDefinitionMap.get(_qualifier).get(clazz);
|
||||
}
|
||||
public hasPouchDefinition(type: Object, qualifier?: string | symbol): boolean {
|
||||
return undefined === this.getPouchDefinition(type, qualifier) ? false : true;
|
||||
public hasPouchDefinition(clazz: ClassType, qualifier?: PropertyType): boolean {
|
||||
return undefined === this.getPouchDefinition(clazz, qualifier) ? false : true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
Construtorable,
|
||||
ClassType,
|
||||
DecoratorType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
import {
|
||||
|
@ -19,19 +20,16 @@ class DefaultPouchFactory extends AbstractPouchFactory implements PouchFactory,
|
|||
public constructor() {
|
||||
super();
|
||||
}
|
||||
public getPouch(qualifier: PropertyType, clazz: ClassType, ...args: any[]): any {
|
||||
|
||||
public getPouch<T>(type: Construtorable<T>, ...args: any[]): T {
|
||||
let qualifier = validateQualifier(type.prototype, undefined);
|
||||
return this.getPouchByQualifier(type, qualifier, args);
|
||||
return null;
|
||||
}
|
||||
public getPouchByType(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any {
|
||||
let _qualifier = validateQualifier(clazz, qualifier);
|
||||
|
||||
public getPouchByQualifier<T>(type: Construtorable<T>, qualifier: string | symbol, ...args: any[]): T {
|
||||
let clazz: Function = type.prototype;
|
||||
let instance: T;
|
||||
return instance;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default DefaultPouchFactory;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
Construtorable,
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
import SingletonPouchRegistry from '@loafer/pouches/factory/config/SingletonPouchRegistry';
|
||||
|
@ -9,44 +10,71 @@ import {
|
|||
} from '@loafer/pouches/util/qualifier';
|
||||
|
||||
class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
|
||||
protected singletonInstanceMap: Map<string | symbol, Map<Object, any>>;
|
||||
protected singletonInstanceMap: Map<PropertyType, Map<ClassType, any>>;
|
||||
|
||||
protected constructor() {
|
||||
}
|
||||
|
||||
public registerSingleton(pouch: any, qualifier?: string | symbol): void {
|
||||
let type: Object = Object.getPrototypeOf(pouch);
|
||||
const _qualifier = validateQualifier(type, qualifier);
|
||||
public registerSingleton(pouch: any, qualifier?: PropertyType): void {
|
||||
let clazz: ClassType = Object.getPrototypeOf(pouch);
|
||||
const _qualifier = validateQualifier(clazz, qualifier);
|
||||
|
||||
if (this._hasSingleton(type, _qualifier)) {
|
||||
throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is exist already`);
|
||||
if (this._hasSingleton(_qualifier, clazz)) {
|
||||
throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is exist already`);
|
||||
}
|
||||
let map = this.singletonInstanceMap.get(_qualifier);
|
||||
if (undefined === map) {
|
||||
map = new Map();
|
||||
this.singletonInstanceMap.set(_qualifier, map);
|
||||
}
|
||||
map.set(type, pouch);
|
||||
}
|
||||
public getSingleton<T>(target: Construtorable<T>, qualifier?: string | symbol): T {
|
||||
let type = target.prototype;
|
||||
return this._getSingleton(type, qualifier);
|
||||
}
|
||||
public hasSingleton<T>(target: Construtorable<T>, qualifier?: string | symbol): boolean {
|
||||
return this._hasSingleton(target.prototype, qualifier);
|
||||
map.set(clazz, pouch);
|
||||
}
|
||||
|
||||
private _getSingleton<T>(type: Object, qualifier?: string | symbol): T {
|
||||
const _qualifier = validateQualifier(type, qualifier);
|
||||
public getSingleton(qualifier: PropertyType, clazz?: ClassType): any {
|
||||
return this._getSingleton(qualifier, clazz);
|
||||
}
|
||||
public getSingletonByClass(clazz: ClassType, qualifier?: PropertyType): any {
|
||||
const _qualifier = validateQualifier(clazz, qualifier);
|
||||
return this._getSingleton(_qualifier, clazz);
|
||||
}
|
||||
public hasSingleton(qualifier: PropertyType, clazz?: ClassType): boolean {
|
||||
return this._hasSingleton(qualifier, clazz);
|
||||
}
|
||||
public hasSingletonByClass(clazz: ClassType, qualifier?: PropertyType): boolean {
|
||||
const _qualifier = validateQualifier(clazz, qualifier);
|
||||
return this._hasSingleton(_qualifier, clazz);
|
||||
}
|
||||
|
||||
if (!this.singletonInstanceMap.has(_qualifier)) {
|
||||
|
||||
private _getSingleton<T>(qualifier: PropertyType, clazz?: ClassType): T {
|
||||
if (!this.singletonInstanceMap.has(qualifier)) {
|
||||
return undefined;
|
||||
}
|
||||
return this.singletonInstanceMap.get(_qualifier).get(type);
|
||||
let map = this.singletonInstanceMap.get(qualifier);
|
||||
let instance;
|
||||
try {
|
||||
instance = this._getInstance(map, clazz);
|
||||
} catch(e) {
|
||||
throw new Error(`Type of Pouch[${qualifier}] cannot be specified(count is ${map.size}).`);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private _hasSingleton(type: Object, qualifier?: string | symbol): boolean {
|
||||
return undefined === this._getSingleton(type, qualifier) ? false : true;
|
||||
private _hasSingleton(qualifier: PropertyType, clazz?: ClassType): boolean {
|
||||
return undefined === this._getSingleton(qualifier, clazz) ? false : true;
|
||||
}
|
||||
|
||||
private _getInstance(map: Map<ClassType, any>, clazz?: ClassType): any {
|
||||
if (undefined !== clazz) {
|
||||
return map.get(clazz);
|
||||
}
|
||||
const count = map.size;
|
||||
if (1 < count) {
|
||||
throw new Error(`Type of Pouch cannot be specified(count is ${count}).`);
|
||||
}
|
||||
for (let value of Array.from(map.values())) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
import { Construtorable } from '@loafer/core/constants';
|
||||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
|
||||
|
||||
interface PouchDefinitionRegistry {
|
||||
registerPouchDefinition(pouchDefinition: PouchDefinition): void;
|
||||
removePouchDefinition(type: Object, qualifier?: string | symbol): void;
|
||||
getPouchDefinition(type: Object, qualifier?: string | symbol): PouchDefinition;
|
||||
hasPouchDefinition(type: Object, qualifier?: string | symbol): boolean;
|
||||
removePouchDefinition(clazz: ClassType, qualifier?: PropertyType): void;
|
||||
getPouchDefinition(clazz: ClassType, qualifier?: PropertyType): PouchDefinition;
|
||||
hasPouchDefinition(clazz: ClassType, qualifier?: PropertyType): boolean;
|
||||
}
|
||||
|
||||
export default PouchDefinitionRegistry;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { ClassType } from '@loafer/core/constants';
|
||||
import getClassMetadata from '@loafer/core/util/metadata/getClassMetadata';
|
||||
|
||||
import { POUCH_INJECT_DEFINITION } from '@loafer/pouches/constants';
|
||||
import InjectDefinition from '@loafer/pouches/definition/InjectDefinition';
|
||||
|
||||
export const getInjectDefinition =
|
||||
(target: Object, isCreate: boolean = false) =>
|
||||
getClassMetadata(target, POUCH_INJECT_DEFINITION, InjectDefinition, isCreate);
|
||||
(clazz: ClassType, isCreate: boolean = false) =>
|
||||
getClassMetadata(clazz, POUCH_INJECT_DEFINITION, InjectDefinition, isCreate);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
export const validateQualifier = (type: Object, qualifier: string | symbol) => {
|
||||
return undefined === qualifier ? type.constructor.name : qualifier;
|
||||
import {
|
||||
ClassType,
|
||||
PropertyType,
|
||||
} from '@loafer/core/constants';
|
||||
|
||||
export const validateQualifier = (clazz: ClassType, qualifier: PropertyType) => {
|
||||
return undefined === qualifier ? clazz.constructor.name : qualifier;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue
Block a user