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