AppContext ing
This commit is contained in:
parent
09226de460
commit
01bd5e5f94
|
@ -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<AppContext> {
|
||||
const appContext = new Promise<AppContext>(resolve => {
|
||||
const context = AppContext.getContext();
|
||||
const context = AppContext.getInstance();
|
||||
resolve(context);
|
||||
});
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
41
src/ts/@overflow/commons/context/AppContext.ts
Normal file
41
src/ts/@overflow/commons/context/AppContext.ts
Normal file
|
@ -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<T>(type: ClassConstructor<T>, ...args: any[]): T {
|
||||
return this._pouchFactory.getPouch(type, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* getPouchByQualifier
|
||||
*/
|
||||
public getPouchByQualifier<T>(type: ClassConstructor<T>, 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;
|
|
@ -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<T>(type: ClassConstructor<T>, ...args: any[]): T {
|
||||
let clazz = type.prototype;
|
||||
let clazz: Function = type.prototype;
|
||||
let instance = Object.create(clazz);
|
||||
instance.constructor.apply(instance, args);
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -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<number, InjectConfig>;
|
||||
}
|
||||
|
||||
class PouchInjectDefinition {
|
||||
protected target: Object;
|
||||
protected injectMap: Map<string | symbol, InjectItem>;
|
||||
|
||||
public constructor(target: Object) {
|
||||
this.target = target;
|
||||
this.injectMap = new Map();
|
||||
}
|
||||
|
||||
public get injectors(): Map<string | symbol, InjectItem> {
|
||||
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;
|
29
src/ts/@overflow/commons/context/pouches/constants.ts
Normal file
29
src/ts/@overflow/commons/context/pouches/constants.ts
Normal file
|
@ -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<T> = {new(...args: any[]): T};
|
66
src/ts/@overflow/commons/context/pouches/decorator/Inject.ts
Normal file
66
src/ts/@overflow/commons/context/pouches/decorator/Inject.ts
Normal file
|
@ -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 <TFunction extends Function>(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<any>): TypedPropertyDescriptor<any> | 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;
|
|
@ -0,0 +1,7 @@
|
|||
interface InjectConfig {
|
||||
qualifier?: string | symbol;
|
||||
required?: boolean;
|
||||
type?: any;
|
||||
}
|
||||
|
||||
export default InjectConfig;
|
|
@ -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 = <TFunction extends Function>(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 = <T>(target: Object, propertyKey: string | symbol,
|
||||
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => {
|
||||
throw new Error('Cannot apply @Injectable decorator on method.');
|
||||
// return descriptor;
|
||||
};
|
||||
|
||||
const getPouchDefinition = <TFunction extends Function>(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;
|
|
@ -0,0 +1,14 @@
|
|||
import * as METADATA from '../constants';
|
||||
import PouchDefinition from '../config/PouchDefinition';
|
||||
|
||||
const PostConstruct = (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
|
||||
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;
|
|
@ -0,0 +1,14 @@
|
|||
import * as METADATA from '../constants';
|
||||
import PouchDefinition from '../config/PouchDefinition';
|
||||
|
||||
const PreDestroy = (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> => {
|
||||
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;
|
|
@ -0,0 +1,16 @@
|
|||
import * as METADATA from '../constants';
|
||||
import PouchDefinition from '../config/PouchDefinition';
|
||||
|
||||
const Qualifier = (value: string | symbol) => {
|
||||
return <TFunction extends Function>(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;
|
17
src/ts/@overflow/commons/context/pouches/decorator/Scope.ts
Normal file
17
src/ts/@overflow/commons/context/pouches/decorator/Scope.ts
Normal file
|
@ -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 <TFunction extends Function>(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;
|
195
src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts
Normal file
195
src/ts/@overflow/commons/context/pouches/factory/PouchFactory.ts
Normal file
|
@ -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<Function, PouchDefinition>;
|
||||
private pouchInstanceMap: Map<Function, Map<string | symbol, any>>;
|
||||
|
||||
public constructor() {
|
||||
this.pouchDefinitionMap = new Map();
|
||||
this.pouchInstanceMap = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* getPouch
|
||||
*/
|
||||
public getPouch<T>(type: ClassConstructor<T>, ...args: any[]): T {
|
||||
let qualifier = POUCH_DEFAULT_QUALIFIER;
|
||||
return this.getPouchByQualifier(type, qualifier, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* getPouchByQualifier
|
||||
*/
|
||||
public getPouchByQualifier<T>(type: ClassConstructor<T>, 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<T>(type: ClassConstructor<T>, 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<string | symbol, InjectItem> = 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<number, InjectConfig>): 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<string | symbol, any> = this.pouchInstanceMap.get(clazz);
|
||||
|
||||
if (undefined === instanceMap) {
|
||||
instanceMap = new Map();
|
||||
this.pouchInstanceMap.set(clazz, instanceMap);
|
||||
}
|
||||
|
||||
instanceMap.set(qualifier, instance);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default PouchFactory;
|
|
@ -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() {
|
||||
|
|
|
@ -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<SigninPayload>): 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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user