This commit is contained in:
crusader 2017-08-01 10:47:50 +09:00
parent a115e94083
commit b7aea7ff82
10 changed files with 59 additions and 50 deletions

View File

@ -3,11 +3,12 @@ import ConfigurationDefinition from '@loafer/context/definition/ConfigurationDef
import { getConfigurationDefinition } from '@loafer/context/util/metadata'; import { getConfigurationDefinition } from '@loafer/context/util/metadata';
import GetAppContext from '@loafer/context'; import GetAppContext from '@loafer/context';
import { DEFAULT_QUALIFIER, InjectableSterotype } from '@loafer/pouches/constants'; import { InjectableSterotype } from '@loafer/pouches/constants';
import DefaultPouchFactory from '@loafer/pouches/factory/implement/DefaultPouchFactory'; import DefaultPouchFactory from '@loafer/pouches/factory/implement/DefaultPouchFactory';
import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry'; import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry';
import { validateQualifier } from '@loafer/pouches/util/qualifier';
const Configuration = (qualifier: string | symbol = DEFAULT_QUALIFIER ) => createDecorator('Configuration', { const Configuration = (qualifier?: string | symbol ) => createDecorator('Configuration', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => { classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let configurationDefinition: ConfigurationDefinition = getConfigurationDefinition(target.prototype, false); let configurationDefinition: ConfigurationDefinition = getConfigurationDefinition(target.prototype, false);
if (undefined !== configurationDefinition) { if (undefined !== configurationDefinition) {
@ -16,7 +17,7 @@ const Configuration = (qualifier: string | symbol = DEFAULT_QUALIFIER ) => creat
configurationDefinition = getConfigurationDefinition(target, true); configurationDefinition = getConfigurationDefinition(target, true);
configurationDefinition.Stereotype = InjectableSterotype.CONFIGURATION; configurationDefinition.Stereotype = InjectableSterotype.CONFIGURATION;
configurationDefinition.Qualifier = qualifier; configurationDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory(); let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory();
let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory; let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory;

View File

@ -3,19 +3,19 @@ import InjectableDefinition from '@loafer/context/definition/InjectableDefinitio
import { getInjectableDefinition } from '@loafer/context/util/metadata'; import { getInjectableDefinition } from '@loafer/context/util/metadata';
import GetAppContext from '@loafer/context'; import GetAppContext from '@loafer/context';
import { DEFAULT_QUALIFIER } from '@loafer/pouches/constants'; import { validateQualifier } from '@loafer/pouches/util/qualifier';
import DefaultPouchFactory from '@loafer/pouches/factory/implement/DefaultPouchFactory'; import DefaultPouchFactory from '@loafer/pouches/factory/implement/DefaultPouchFactory';
import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry'; import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry';
const Injectable = (qualifier: string | symbol = DEFAULT_QUALIFIER ) => createDecorator('Injectable', { const Injectable = (qualifier?: string | symbol ) => createDecorator('Injectable', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => { classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, false); let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, false);
if (undefined !== injectableDefinition) { if (undefined !== injectableDefinition) {
throw new Error('Cannot apply @Injectable decorator multiple times.'); throw new Error('Cannot apply @Injectable decorator multiple times.');
} }
injectableDefinition = getInjectableDefinition(target, true); injectableDefinition = getInjectableDefinition(target.prototype, true);
injectableDefinition.Qualifier = qualifier; injectableDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory(); let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory();
let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory; let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory;

View File

@ -3,11 +3,12 @@ import InjectableDefinition from '@loafer/context/definition/InjectableDefinitio
import { getInjectableDefinition } from '@loafer/context/util/metadata'; import { getInjectableDefinition } from '@loafer/context/util/metadata';
import GetAppContext from '@loafer/context'; import GetAppContext from '@loafer/context';
import { DEFAULT_QUALIFIER, InjectableSterotype } from '@loafer/pouches/constants'; import { InjectableSterotype } from '@loafer/pouches/constants';
import { validateQualifier } from '@loafer/pouches/util/qualifier';
import DefaultPouchFactory from '@loafer/pouches/factory/implement/DefaultPouchFactory'; import DefaultPouchFactory from '@loafer/pouches/factory/implement/DefaultPouchFactory';
import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry'; import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry';
const Service = (qualifier: string | symbol = DEFAULT_QUALIFIER ) => createDecorator('Service', { const Service = (qualifier?: string | symbol ) => createDecorator('Service', {
classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => { classDecorator: <TFunction extends Function>(target: TFunction): TFunction | void => {
let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, false); let injectableDefinition: InjectableDefinition = getInjectableDefinition(target.prototype, false);
if (undefined !== injectableDefinition) { if (undefined !== injectableDefinition) {
@ -16,7 +17,7 @@ const Service = (qualifier: string | symbol = DEFAULT_QUALIFIER ) => createDecor
injectableDefinition = getInjectableDefinition(target, true); injectableDefinition = getInjectableDefinition(target, true);
injectableDefinition.Stereotype = InjectableSterotype.SERVICE; injectableDefinition.Stereotype = InjectableSterotype.SERVICE;
injectableDefinition.Qualifier = qualifier; injectableDefinition.Qualifier = validateQualifier(target.prototype, qualifier);
let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory(); let pouchFactory: DefaultPouchFactory = GetAppContext().getPouchFactory();
let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory; let pouchDefinitionRegistry = <PouchDefinitionRegistry>pouchFactory;

View File

@ -1,5 +1,3 @@
export * from './reflect'; export * from './reflect';
export * from './stereotype'; export * from './stereotype';
export * from './types'; export * from './types';
export const DEFAULT_QUALIFIER = Symbol('__DEFAULT_QUALIFIER__');

View File

@ -1,5 +1,5 @@
import * as METADATA from '@loafer/pouches/constants'; import { InjectSterotype } from '@loafer/pouches/constants';
import { DEFAULT_QUALIFIER, InjectSterotype } from '@loafer/pouches/constants'; 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'; import * as CoreConstants from '@loafer/core/constants';
@ -27,9 +27,7 @@ class InjectDefinition {
* addInject * addInject
*/ */
public addInject(injectConfig: InjectConfig, propertyKey: string | symbol, parameterIndex?: number): void { public addInject(injectConfig: InjectConfig, propertyKey: string | symbol, parameterIndex?: number): void {
if (undefined === injectConfig.qualifier) { injectConfig.qualifier = validateQualifier(this.target, injectConfig.qualifier);
injectConfig.qualifier = DEFAULT_QUALIFIER;
}
if (undefined === injectConfig.required) { if (undefined === injectConfig.required) {
injectConfig.required = false; injectConfig.required = false;
} }

View File

@ -9,7 +9,7 @@ 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<Object, Map<string | symbol, PouchDefinition>>; protected pouchDefinitionMap: Map<string | symbol, Map<Object, PouchDefinition>>;
public constructor() { public constructor() {
super(); super();
this.pouchDefinitionMap = new Map(); this.pouchDefinitionMap = new Map();
@ -17,33 +17,35 @@ abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implem
public registerPouchDefinition(pouchDefinition: PouchDefinition): void { public registerPouchDefinition(pouchDefinition: PouchDefinition): void {
let type = pouchDefinition.Type; let type = pouchDefinition.Type;
let qualifier = pouchDefinition.Qualifier; let qualifier = validateQualifier(type, pouchDefinition.Qualifier);
if (this.hasPouchDefinition(type, qualifier)) { if (this.hasPouchDefinition(type, qualifier)) {
throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is exist already`); throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is exist already`);
} }
let map = this.pouchDefinitionMap.get(type); let map = this.pouchDefinitionMap.get(qualifier);
if (undefined === map) { if (undefined === map) {
map = new Map(); map = new Map();
this.pouchDefinitionMap.set(qualifier, map);
} }
map.set(qualifier, pouchDefinition); map.set(type, pouchDefinition);
} }
public removePouchDefinition(type: Object, qualifier?: string | symbol): void { public removePouchDefinition(type: Object, qualifier?: string | symbol): void {
if (!this.hasPouchDefinition(type, qualifier)) { const _qualifier = validateQualifier(type, qualifier);
if (!this.hasPouchDefinition(type, _qualifier)) {
throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is not exist`); throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is not exist`);
} }
const _qualifier = validateQualifier(qualifier); this.pouchDefinitionMap.get(_qualifier).delete(type);
this.pouchDefinitionMap.get(type).delete(_qualifier); if (0 === this.pouchDefinitionMap.get(_qualifier).size) {
if (0 === this.pouchDefinitionMap.get(type).size) { this.pouchDefinitionMap.delete(_qualifier);
this.pouchDefinitionMap.delete(type);
} }
} }
public getPouchDefinition(type: Object, qualifier?: string | symbol): PouchDefinition { public getPouchDefinition(type: Object, qualifier?: string | symbol): PouchDefinition {
if (!this.pouchDefinitionMap.has(type)) { const _qualifier = validateQualifier(type, qualifier);
if (!this.pouchDefinitionMap.has(_qualifier)) {
return undefined; return undefined;
} }
const _qualifier = validateQualifier(qualifier); return this.pouchDefinitionMap.get(_qualifier).get(type);
return this.pouchDefinitionMap.get(type).get(qualifier);
} }
public hasPouchDefinition(type: Object, qualifier?: string | symbol): boolean { public hasPouchDefinition(type: Object, qualifier?: string | symbol): boolean {
return undefined === this.getPouchDefinition(type, qualifier) ? false : true; return undefined === this.getPouchDefinition(type, qualifier) ? false : true;

View File

@ -5,8 +5,10 @@ import {
import { import {
PouchScope, PouchScope,
DEFAULT_QUALIFIER,
} from '@loafer/pouches/constants'; } from '@loafer/pouches/constants';
import {
validateQualifier,
} from '@loafer/pouches/util/qualifier';
import PouchFactory from '@loafer/pouches/factory/PouchFactory'; import PouchFactory from '@loafer/pouches/factory/PouchFactory';
import AbstractPouchFactory from '@loafer/pouches/factory/implement/AbstractPouchFactory'; import AbstractPouchFactory from '@loafer/pouches/factory/implement/AbstractPouchFactory';
@ -19,7 +21,7 @@ class DefaultPouchFactory extends AbstractPouchFactory implements PouchFactory,
} }
public getPouch<T>(type: Construtorable<T>, ...args: any[]): T { public getPouch<T>(type: Construtorable<T>, ...args: any[]): T {
let qualifier = DEFAULT_QUALIFIER; let qualifier = validateQualifier(type.prototype, undefined);
return this.getPouchByQualifier(type, qualifier, args); return this.getPouchByQualifier(type, qualifier, args);
} }

View File

@ -9,33 +9,44 @@ import {
} from '@loafer/pouches/util/qualifier'; } from '@loafer/pouches/util/qualifier';
class DefaultSingletonPouchRegistry implements SingletonPouchRegistry { class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
protected singletonInstanceMap: Map<Object, Map<string | symbol, any>>; protected singletonInstanceMap: Map<string | symbol, Map<Object, any>>;
protected constructor() { protected constructor() {
} }
public registerSingleton(pouch: any, qualifier?: string | symbol): void { public registerSingleton(pouch: any, qualifier?: string | symbol): void {
let type = Object.getPrototypeOf(pouch); let type: Object = Object.getPrototypeOf(pouch);
const _qualifier = validateQualifier(qualifier); const _qualifier = validateQualifier(type, qualifier);
if (this.hasSingleton(type, qualifier)) { if (this._hasSingleton(type, _qualifier)) {
throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is exist already`); throw new Error(`Pouch Definition[${type.constructor.name}:${qualifier}] is exist already`);
} }
let map = this.singletonInstanceMap.get(type); let map = this.singletonInstanceMap.get(_qualifier);
if (undefined === map) { if (undefined === map) {
map = new Map(); map = new Map();
this.singletonInstanceMap.set(_qualifier, map);
} }
map.set(qualifier, pouch); map.set(type, pouch);
} }
public getSingleton<T>(type: Construtorable<T>, qualifier?: string | symbol): T { public getSingleton<T>(target: Construtorable<T>, qualifier?: string | symbol): T {
if (!this.singletonInstanceMap.has(type)) { 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 {
const _qualifier = validateQualifier(type, qualifier);
if (!this.singletonInstanceMap.has(_qualifier)) {
return undefined; return undefined;
} }
const _qualifier = validateQualifier(qualifier); return this.singletonInstanceMap.get(_qualifier).get(type);
return this.singletonInstanceMap.get(type).get(qualifier);
} }
public hasSingleton<T>(type: Construtorable<T>, qualifier?: string | symbol): boolean {
return undefined === this.getSingleton(type, qualifier) ? false : true; private _hasSingleton(type: Object, qualifier?: string | symbol): boolean {
return undefined === this._getSingleton(type, qualifier) ? false : true;
} }
} }

View File

@ -1,7 +1,3 @@
import { export const validateQualifier = (type: Object, qualifier: string | symbol) => {
DEFAULT_QUALIFIER, return undefined === qualifier ? type.constructor.name : qualifier;
} from '@loafer/pouches/constants';
export const validateQualifier = (qualifier: string | symbol) => {
return undefined === qualifier ? DEFAULT_QUALIFIER : qualifier;
}; };

View File

@ -2,7 +2,7 @@ import Inject from '@loafer/pouches/decorator/Inject';
import WebSocketRPC from '../websocket/WebSocketRPC'; import WebSocketRPC from '../websocket/WebSocketRPC';
abstract class Service { abstract class Service {
@Inject({required: false}) @Inject({required: true})
private webSocketRPC: WebSocketRPC; private webSocketRPC: WebSocketRPC;
private name: string; private name: string;
protected constructor(name: string) { protected constructor(name: string) {