diff --git a/src/ts/@overflow/app/index.tsx b/src/ts/@overflow/app/index.tsx index fefe874..c31dcb6 100644 --- a/src/ts/@overflow/app/index.tsx +++ b/src/ts/@overflow/app/index.tsx @@ -42,7 +42,7 @@ import { import * as injectTapEventPlugin from 'react-tap-event-plugin'; import Platform from '@overflow/commons/platform'; -import AppContext from '@overflow/commons/context'; +import AppContext from '@overflow/commons/context/AppContext'; import * as AppContextLifecycleActions from '@overflow/commons/context/redux/action/lifecycle'; import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC'; import ReducerContext from '@overflow/commons/redux/ReducerContext'; @@ -86,8 +86,8 @@ class Application { this.displayLoading(); this.context = await this.initContext(); - // this.rpcClient = await this.initRpcClient(); - // this.context.put(this.rpcClient); + this.rpcClient = await this.initRpcClient(); + this.context.PouchFactory.registerPouch(this.rpcClient); await this.initRedux(); @@ -102,7 +102,7 @@ class Application { private initContext(): Promise { const appContext = new Promise(resolve => { - const context = AppContext.getContext(); + const context = AppContext.getInstance(); resolve(context); }); diff --git a/src/ts/@overflow/commons/api/Service.ts b/src/ts/@overflow/commons/api/Service.ts index 984e514..1635082 100644 --- a/src/ts/@overflow/commons/api/Service.ts +++ b/src/ts/@overflow/commons/api/Service.ts @@ -1,8 +1,8 @@ -import inject from '../context/decorator/inject'; +import Inject from '../context/pouches/decorator/Inject'; import WebSocketRPC from '../websocket/WebSocketRPC'; abstract class Service { - @inject({qualifier: '11111', required: false}) + @Inject({required: false}) private webSocketRPC: WebSocketRPC; private name: string; protected constructor(name: string) { diff --git a/src/ts/@overflow/commons/context/AppContext.ts b/src/ts/@overflow/commons/context/AppContext.ts new file mode 100644 index 0000000..cb9e48c --- /dev/null +++ b/src/ts/@overflow/commons/context/AppContext.ts @@ -0,0 +1,41 @@ +import PouchFactory from './pouches/factory/PouchFactory'; +import { + ClassConstructor, +} from './pouches/constants'; + +class AppContext { + private static _instance: AppContext; + private _pouchFactory: PouchFactory; + + public constructor() { + this._pouchFactory = new PouchFactory(); + } + + public get PouchFactory(): PouchFactory { + return this._pouchFactory; + } + + /** + * getPouch + */ + public getPouch(type: ClassConstructor, ...args: any[]): T { + return this._pouchFactory.getPouch(type, args); + } + + /** + * getPouchByQualifier + */ + public getPouchByQualifier(type: ClassConstructor, qualifier: string | symbol, ...args: any[]): T { + return this._pouchFactory.getPouchByQualifier(type, qualifier, args); + } + + + public static getInstance(): AppContext { + if (undefined === AppContext._instance) { + AppContext._instance = new AppContext(); + } + return AppContext._instance; + } +} + +export default AppContext; diff --git a/src/ts/@overflow/commons/context/index.ts b/src/ts/@overflow/commons/context/index.ts index c0b1958..b26f9ed 100644 --- a/src/ts/@overflow/commons/context/index.ts +++ b/src/ts/@overflow/commons/context/index.ts @@ -21,7 +21,7 @@ class AppContext { this.instanceMap.set(aaa, instance); } - private setValue(type: any, target: object): void { + private setValue(type: Function, target: object): void { if (type.constructor === Object) { console.log('Object'); return; @@ -44,7 +44,7 @@ class AppContext { } public static getService(type: ClassConstructor, ...args: any[]): T { - let clazz = type.prototype; + let clazz: Function = type.prototype; let instance = Object.create(clazz); instance.constructor.apply(instance, args); diff --git a/src/ts/@overflow/commons/context/pouches/config/PouchDefinition.ts b/src/ts/@overflow/commons/context/pouches/config/PouchDefinition.ts new file mode 100644 index 0000000..1d4b442 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/config/PouchDefinition.ts @@ -0,0 +1,59 @@ +import { PouchScope, POUCH_DEFAULT_QUALIFIER } from '../constants'; + +class PouchDefinition { + protected _type: Function; + protected _scope: PouchScope = PouchScope.SINGLETON; + protected _qualifier: string | symbol; + protected _postConstruct: string[] = null; + protected _preDestroy: string[] = null; + + public constructor(type: Function) { + this._type = type; + this._qualifier = POUCH_DEFAULT_QUALIFIER; + } + + public get type(): Function { + return this._type; + } + + public get scope(): PouchScope { + return this._scope; + } + + public set scope(scope: PouchScope) { + this._scope = scope; + } + + public get qualifier(): string | symbol { + return this._qualifier; + } + + public set qualifier(qualifier: string | symbol) { + this._qualifier = qualifier; + } + + public get postConstruct(): string[] { + return this._postConstruct; + } + + public addPostConstruct(postConstruct: string): void { + if (null == this._postConstruct) { + this._postConstruct = []; + } + this._postConstruct.push(postConstruct); + } + + public get preDestroy(): string[] { + return this._preDestroy; + } + + public addPreDestroy(preDestroy: string): void { + if (null == this._preDestroy) { + this._preDestroy = []; + } + this._preDestroy.push(preDestroy); + } + +} + +export default PouchDefinition; diff --git a/src/ts/@overflow/commons/context/pouches/config/PouchInjectDefinition.ts b/src/ts/@overflow/commons/context/pouches/config/PouchInjectDefinition.ts new file mode 100644 index 0000000..b93585c --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/config/PouchInjectDefinition.ts @@ -0,0 +1,92 @@ +import * as METADATA from '../constants'; +import { DecoratorType, POUCH_DEFAULT_QUALIFIER } from '../constants'; +import InjectConfig from '../decorator/InjectConfig'; + +export interface InjectItem { + decoratorType: DecoratorType; + propertyConfig?: InjectConfig; + parameterConfigMap?: Map; +} + +class PouchInjectDefinition { + protected target: Object; + protected injectMap: Map; + + public constructor(target: Object) { + this.target = target; + this.injectMap = new Map(); + } + + public get injectors(): Map { + return this.injectMap; + } + + /** + * addInject + */ + public addInject(injectConfig: InjectConfig, propertyKey: string | symbol, parameterIndex?: number): void { + if (undefined === injectConfig.qualifier) { + injectConfig.qualifier = POUCH_DEFAULT_QUALIFIER; + } + if (undefined === injectConfig.required) { + injectConfig.required = false; + } + + if(typeof parameterIndex === 'number') { + this.addInjectParameter(injectConfig, propertyKey, parameterIndex); + } else { + this.addInjectProperty(injectConfig, propertyKey); + } + } + + private addInjectParameter(injectConfig: InjectConfig, propertyKey: string | symbol, parameterIndex: number): void { + let injectItem: InjectItem; + let parameterTypes: any[] = Reflect.getMetadata(METADATA.DESIGN_PARAMTYPES, this.target, propertyKey); + + if (undefined === injectConfig.type) { + injectConfig.type = parameterTypes[parameterIndex]; + } + + if (this.injectMap.has(propertyKey)) { + injectItem = this.injectMap.get(propertyKey); + } else { + injectItem = { + decoratorType: DecoratorType.PARAMETER, + }; + this.injectMap.set(propertyKey, injectItem); + } + + if (null !== injectItem.parameterConfigMap) { + if (injectItem.parameterConfigMap.has(parameterIndex)) { + throw new Error(`Cannot apply @inject decorator on one parameter[${propertyKey}:${parameterIndex}] multiple times.`); + } + } else { + injectItem.parameterConfigMap = new Map(); + } + + injectItem.parameterConfigMap.set(parameterIndex, injectConfig); + + } + + private addInjectProperty(injectConfig: InjectConfig, propertyKey: string | symbol): void { + if (this.injectMap.has(propertyKey)) { + throw new Error(`Cannot apply @inject decorator on one property[${propertyKey}] multiple times.`); + } + + let propertyType: any = Reflect.getMetadata(METADATA.DESIGN_TYPE, this.target, propertyKey); + + if (undefined === injectConfig.type) { + injectConfig.type = propertyType; + } + + let injectItem: InjectItem = { + decoratorType: DecoratorType.PROPERTY, + propertyConfig: injectConfig, + }; + + this.injectMap.set(propertyKey, injectItem); + } + +} + +export default PouchInjectDefinition; diff --git a/src/ts/@overflow/commons/context/pouches/constants.ts b/src/ts/@overflow/commons/context/pouches/constants.ts new file mode 100644 index 0000000..556759d --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/constants.ts @@ -0,0 +1,29 @@ +// used to access design time types +export const DESIGN_TYPE = 'design:type'; +// used to access design time types +export const DESIGN_PARAMTYPES = 'design:paramtypes'; +// used to access design time types +export const DESIGN_RETURNTYPE = 'design:returntype'; + + +// used to store types to be injected +export const POUCH_DEFINITION = 'loafer:pouch_definition'; + +// used to store types to be injected +export const POUCH_INJECT_DEFINITION = 'loafer:pouch_inject_definition'; + +export const POUCH_DEFAULT_QUALIFIER = Symbol('__QUALIFIER__'); + +export enum PouchScope { + SINGLETON, + PROTOTYPE, +} + +export enum DecoratorType { + CLASS, + PROPERTY, + PARAMETER, + METHOD, +} + +export type ClassConstructor = {new(...args: any[]): T}; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Inject.ts b/src/ts/@overflow/commons/context/pouches/decorator/Inject.ts new file mode 100644 index 0000000..9eab2e0 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/decorator/Inject.ts @@ -0,0 +1,66 @@ +import * as METADATA from '../constants'; +import { POUCH_DEFAULT_QUALIFIER } from '../constants'; +import InjectConfig from './InjectConfig'; +import PouchInjectDefinition from '../config/PouchInjectDefinition'; + +const Inject = (injectConfig: InjectConfig = {}) => { + return (...args: any[]) => { + switch(args.length) { + case 1: + return injectClass.apply(this, args); + case 2: + return injectProperty.apply(this, args); + case 3: + if(typeof args[2] === 'number') { + return injectParameter.apply(this, args); + } + return injectMethod.apply(this, args); + default: + throw new Error('@Inject decorators are not valid here!'); + } + }; +}; + +const injectClass = (injectConfig: InjectConfig = {}) => { + return (target: TFunction): TFunction | void => { + throw new Error('Cannot apply @Inject decorator on Class.'); + }; +}; + +const injectProperty = (injectConfig: InjectConfig = {}) => { + return (target: Object, propertyKey: string | symbol): void => { + let pouchInjectDefinition: PouchInjectDefinition = getPouchInjectDefinition(target); + pouchInjectDefinition.addInject(injectConfig, propertyKey); + }; +}; + +const injectParameter = (injectConfig: InjectConfig = {}) => { + return (target: Object, propertyKey: string | symbol, parameterIndex: number): void => { + let pouchInjectDefinition: PouchInjectDefinition = getPouchInjectDefinition(target); + pouchInjectDefinition.addInject(injectConfig, propertyKey, parameterIndex); + }; +}; + +const injectMethod = (injectConfig: InjectConfig = {}) => { + return (target: Object, propertyKey: string | symbol, + descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void => { + throw new Error('Cannot apply @Inject decorator on Class.'); + + // return descriptor; + }; +}; + + + +const getPouchInjectDefinition = (target: Object) => { + let pouchInjectDefinition: PouchInjectDefinition; + if (Reflect.hasOwnMetadata(METADATA.POUCH_INJECT_DEFINITION, target) !== true) { + pouchInjectDefinition = new PouchInjectDefinition(target); + Reflect.defineMetadata(METADATA.POUCH_INJECT_DEFINITION, pouchInjectDefinition, target); + } else { + pouchInjectDefinition = Reflect.getMetadata(METADATA.POUCH_INJECT_DEFINITION, target); + } + return pouchInjectDefinition; +}; + +export default Inject; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/InjectConfig.ts b/src/ts/@overflow/commons/context/pouches/decorator/InjectConfig.ts new file mode 100644 index 0000000..fe4b687 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/decorator/InjectConfig.ts @@ -0,0 +1,7 @@ +interface InjectConfig { + qualifier?: string | symbol; + required?: boolean; + type?: any; +} + +export default InjectConfig; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Injectable.ts b/src/ts/@overflow/commons/context/pouches/decorator/Injectable.ts new file mode 100644 index 0000000..1f8c137 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/decorator/Injectable.ts @@ -0,0 +1,60 @@ +import * as METADATA from '../constants'; +import PouchDefinition from '../config/PouchDefinition'; + + +const Injectable = (...args: any[]) => { + switch(args.length) { + case 1: + return injectableClass.apply(this, args); + case 2: + return injectableProperty.apply(this, args); + case 3: + if(typeof args[2] === 'number') { + return injectableParameter.apply(this, args); + } + return injectableMethod.apply(this, args); + default: + throw new Error('@Injectable decorators are not valid here!'); + } +}; + + +const injectableClass = (target: TFunction): TFunction | void => { + if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) === true) { + throw new Error('Cannot apply @injectable decorator multiple times.'); + } + + let pouchDefinition: PouchDefinition = getPouchDefinition(target.prototype); + + return target; +}; + + +const injectableProperty = (target: Object, propertyKey: string | symbol): void => { + throw new Error('Cannot apply @Injectable decorator on property.'); +}; + + +const injectableParameter = (target: Object, propertyKey: string | symbol, parameterIndex: number): void => { + throw new Error('Cannot apply @Injectable decorator on parameter.'); +}; + +const injectableMethod = (target: Object, propertyKey: string | symbol, + descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor | void => { + throw new Error('Cannot apply @Injectable decorator on method.'); + // return descriptor; +}; + +const getPouchDefinition = (target: TFunction) => { + let pouchDefinition: PouchDefinition; + if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { + pouchDefinition = new PouchDefinition(target); + Reflect.defineMetadata(METADATA.POUCH_DEFINITION, pouchDefinition, target); + } else { + pouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); + } + return pouchDefinition; +}; + + +export default Injectable; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/PostConstruct.ts b/src/ts/@overflow/commons/context/pouches/decorator/PostConstruct.ts new file mode 100644 index 0000000..9e1ad01 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/decorator/PostConstruct.ts @@ -0,0 +1,14 @@ +import * as METADATA from '../constants'; +import PouchDefinition from '../config/PouchDefinition'; + +const PostConstruct = (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor => { + if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { + throw new Error('Cannot apply @PostConstruct decorator on the not @Injectable class.'); + } + let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); + pouchDefinition.addPostConstruct(propertyKey); + + return descriptor; +}; + +export default PostConstruct; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/PreDestroy.ts b/src/ts/@overflow/commons/context/pouches/decorator/PreDestroy.ts new file mode 100644 index 0000000..3434db0 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/decorator/PreDestroy.ts @@ -0,0 +1,14 @@ +import * as METADATA from '../constants'; +import PouchDefinition from '../config/PouchDefinition'; + +const PreDestroy = (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor => { + if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { + throw new Error('Cannot apply @PreDestroy decorator on the not @Injectable class.'); + } + let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); + pouchDefinition.addPreDestroy(propertyKey); + + return descriptor; +}; + +export default PreDestroy; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Qualifier.ts b/src/ts/@overflow/commons/context/pouches/decorator/Qualifier.ts new file mode 100644 index 0000000..89c02f9 --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/decorator/Qualifier.ts @@ -0,0 +1,16 @@ +import * as METADATA from '../constants'; +import PouchDefinition from '../config/PouchDefinition'; + +const Qualifier = (value: string | symbol) => { + return (target: TFunction): TFunction | void => { + if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { + throw new Error('Cannot apply @Qualifier decorator on the not @Injectable class.'); + } + let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); + pouchDefinition.qualifier = value; + + return target; + }; +}; + +export default Qualifier; diff --git a/src/ts/@overflow/commons/context/pouches/decorator/Scope.ts b/src/ts/@overflow/commons/context/pouches/decorator/Scope.ts new file mode 100644 index 0000000..48819ee --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/decorator/Scope.ts @@ -0,0 +1,17 @@ +import * as METADATA from '../constants'; +import PouchDefinition from '../config/PouchDefinition'; +import { PouchScope } from '../constants'; + +const Scope = (value: PouchScope = PouchScope.SINGLETON) => { + return (target: TFunction): TFunction | void => { + if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, target) !== true) { + throw new Error('Cannot apply @Scope decorator on the not @Injectable class.'); + } + let pouchDefinition: PouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, target); + pouchDefinition.scope = value; + + return target; + }; +}; + +export default Scope; diff --git a/src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts b/src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts new file mode 100644 index 0000000..24d38be --- /dev/null +++ b/src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts @@ -0,0 +1,195 @@ +import * as METADATA from '../constants'; + +import { + ClassConstructor, + DecoratorType, + PouchScope, + POUCH_DEFAULT_QUALIFIER, +} from '../constants'; + +import PouchDefinition from '../config/PouchDefinition'; + +import PouchInjectDefinition, { + InjectItem, +} from '../config/PouchInjectDefinition'; + +import InjectConfig from '../decorator/InjectConfig'; + +class PouchFactory { + private pouchDefinitionMap: Map; + private pouchInstanceMap: Map>; + + public constructor() { + this.pouchDefinitionMap = new Map(); + this.pouchInstanceMap = new Map(); + } + + /** + * getPouch + */ + public getPouch(type: ClassConstructor, ...args: any[]): T { + let qualifier = POUCH_DEFAULT_QUALIFIER; + return this.getPouchByQualifier(type, qualifier, args); + } + + /** + * getPouchByQualifier + */ + public getPouchByQualifier(type: ClassConstructor, qualifier: string | symbol, ...args: any[]): T { + let clazz: Function = type.prototype; + + let instance = this._getPouch(clazz, qualifier, args); + + return instance; + } + + + /** + * registerPouch + */ + public registerPouch(pouch: any, qualifier: string | symbol = POUCH_DEFAULT_QUALIFIER): void { + let clazz = pouch.prototype; + this._putPouchInstance(clazz, qualifier, pouch); + } + + /** + * registerPouch + */ + public registerPouchDefinition(type: ClassConstructor, pouchDefinition: PouchDefinition): void { + let clazz: Function = type.prototype; + if (this.pouchDefinitionMap.has(clazz)) { + throw new Error(`Pouch Definition of [${clazz.name}] is already exist.`); + } + this.pouchDefinitionMap.set(clazz, pouchDefinition); + } + + protected getPouchDefinition(clazz: Function): PouchDefinition { + let pouchDefinition: PouchDefinition = this.pouchDefinitionMap.get(clazz); + if (undefined !== pouchDefinition) { + return pouchDefinition; + } + + if (Reflect.hasOwnMetadata(METADATA.POUCH_DEFINITION, clazz) !== true) { + return null; + } + + pouchDefinition = Reflect.getMetadata(METADATA.POUCH_DEFINITION, clazz); + this.pouchDefinitionMap.set(clazz, pouchDefinition); + + return pouchDefinition; + + } + + protected getPouchInjectDefinition(clazz: Function): PouchInjectDefinition { + if (Reflect.hasOwnMetadata(METADATA.POUCH_INJECT_DEFINITION, clazz) !== true) { + return null; + } + + let pouchInjectDefinition: PouchInjectDefinition = Reflect.getMetadata(METADATA.POUCH_INJECT_DEFINITION, clazz); + + return pouchInjectDefinition; + } + + private _getPouch(clazz: Function, qualifier: string | symbol, ...args: any[]): any { + let pouchDefinition: PouchDefinition = this.getPouchDefinition(clazz); + + let instance: any; + if (null == pouchDefinition) { + if (this._hasPouchInstance(clazz, qualifier)) { + instance = this._getPouchInstance(clazz, qualifier); + } else { + instance = this._newInstance(clazz, pouchDefinition, args); + } + } else { + if (pouchDefinition.scope === PouchScope.PROTOTYPE) { + instance = this._newInstance(clazz, pouchDefinition, args); + } else { + if (this._hasPouchInstance(clazz, qualifier)) { + return this._getPouchInstance(clazz, qualifier); + } + instance = this._newInstance(clazz, pouchDefinition, args); + } + } + + return instance; + } + + private _newInstance(clazz: Function, pouchDefinition: PouchDefinition, ...args: any[]): any { + let instance: any; + instance = Object.create(clazz); + instance.constructor.apply(instance, args); + + this._injectDependency(instance, clazz); + + return instance; + } + + private _injectDependency(target: object, clazz: Function): void { + if (clazz.constructor === Object) { + return; + } + + let pouchInjectDefinition: PouchInjectDefinition = this.getPouchInjectDefinition(clazz); + if (null !== pouchInjectDefinition) { + let injectors: Map = pouchInjectDefinition.injectors; + let propertyDescriptor: any; + injectors.forEach((injectItem, key, map) => { + propertyDescriptor = Object.getOwnPropertyDescriptor(target, key); + + switch (injectItem.decoratorType) { + case DecoratorType.PROPERTY: + this._injectDependencyProperty(target, clazz, key, propertyDescriptor, injectItem.propertyConfig); + break; + case DecoratorType.PARAMETER: + this._injectDependencyParameter(target, propertyDescriptor, injectItem.parameterConfigMap); + break; + default: + break; + } + }); + } + this._injectDependency(target, Object.getPrototypeOf(clazz)); + } + + private _injectDependencyProperty(target: object, clazz: Function, propertyKey: string | symbol, + propertyDescriptor: PropertyDescriptor, injectConfig: InjectConfig): void { + let instance = this.getPouch(injectConfig.type, injectConfig.qualifier); + if (injectConfig.required && undefined === instance) { + throw new Error(`Pouch which used by [${clazz.name}.${propertyKey}] is not exist in the context.`); + } + target[propertyKey] = instance; + } + + private _injectDependencyParameter(target: object, propertyDescriptor: PropertyDescriptor, + parameterConfigs: Map): void { + console.log(''); + } + + private _hasPouchInstance(clazz: Function, qualifier: string | symbol): boolean { + if (!this.pouchInstanceMap.has(clazz) || !this.pouchInstanceMap.get(clazz).has(qualifier)) { + return false; + } + return true; + } + + private _getPouchInstance(clazz: Function, qualifier: string | symbol): any { + if (!this._hasPouchInstance(clazz, qualifier)) { + return null; + } + return this.pouchInstanceMap.get(clazz).get(qualifier); + } + + private _putPouchInstance(clazz: Function, qualifier: string | symbol, instance: any): void { + let instanceMap: Map = this.pouchInstanceMap.get(clazz); + + if (undefined === instanceMap) { + instanceMap = new Map(); + this.pouchInstanceMap.set(clazz, instanceMap); + } + + instanceMap.set(qualifier, instance); + } + +} + +export default PouchFactory; diff --git a/src/ts/@overflow/member/api/service/MemberService.ts b/src/ts/@overflow/member/api/service/MemberService.ts index b1257ea..f81bbbf 100644 --- a/src/ts/@overflow/member/api/service/MemberService.ts +++ b/src/ts/@overflow/member/api/service/MemberService.ts @@ -1,11 +1,11 @@ import Service from '@overflow/commons/api/Service'; import Member from '../model/Member'; -import injectable from '@overflow/commons/context/decorator/injectable'; +import Injectable from '@overflow/commons/context/pouches/decorator/Injectable'; import inject from '@overflow/commons/context/decorator/inject'; -@injectable() +@Injectable export class MemberService extends Service { public constructor() { diff --git a/src/ts/@overflow/member/redux/saga/signIn.ts b/src/ts/@overflow/member/redux/saga/signIn.ts index 30dd57b..7ec2450 100644 --- a/src/ts/@overflow/member/redux/saga/signIn.ts +++ b/src/ts/@overflow/member/redux/saga/signIn.ts @@ -3,7 +3,7 @@ import { call, Effect, fork, put, takeLatest } from 'redux-saga/effects'; import { SagaWatcher } from '@overflow/commons/redux-saga'; -import AppContext from '@overflow/commons/context'; +import AppContext from '@overflow/commons/context/AppContext'; import Action from '@overflow/commons/redux/Action'; import Member from '../../api/model/Member'; @@ -18,7 +18,7 @@ function* signin(action: Action): SagaIterator { // type: types.SENDING_REQUEST, // payload: {sendingRequest: true}, // }); - let memberService = AppContext.getService(MemberService); + let memberService = AppContext.getInstance().getPouch(MemberService); const member = yield call({context: memberService, fn: memberService.signin}, signinId, signinPw);