This commit is contained in:
crusader 2017-08-03 00:11:59 +09:00
parent 14f3fa4b1e
commit 81b76fb8b9
19 changed files with 95 additions and 387 deletions

View File

@ -1,6 +1,6 @@
import {
ClassType,
} from '@loafer/core/constants';
} from '@loafer/core/constants/types';
import AppContext from '@loafer/context/AppContext';
import DefaultAppContext from '@loafer/context/implement/DefaultAppContext';

View File

@ -1,32 +0,0 @@
import { ClassType, DESIGN_RETURNTYPE, PropertyType } from '@loafer/core/constants';
import PouchConfig from '@loafer/context/decorator/PouchConfig';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
class ConfigurationDefinition extends InjectableDefinition {
protected _qualifier: PropertyType = undefined;
protected _pouchMap: Map<string, PouchConfig>;
public constructor(clazz: ClassType) {
super(clazz);
}
public addPouch(propertyKey: string, pouchConfig: PouchConfig): void {
if (undefined === this._pouchMap) {
this._pouchMap = new Map();
}
let returnType: any = Reflect.getMetadata(DESIGN_RETURNTYPE, this._clazz, propertyKey);
if (undefined === pouchConfig.type) {
pouchConfig.type = returnType;
}
this._pouchMap.set(propertyKey, pouchConfig);
}
public get Pouches(): Map<string, PouchConfig> {
return this._pouchMap;
}
}
export default ConfigurationDefinition;

View File

@ -1,7 +1,7 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants';
} from '@loafer/core/constants/types';
import AppContext from '@loafer/context/AppContext';

View File

@ -4,7 +4,7 @@ import { call, fork, take } from 'redux-saga/effects';
import * as LifecycleActions from '../action/lifecycle';
import AppContext from '../../';
import AppContext from '../../AppContext';
function _destroy(): Promise<void> {

View File

@ -1,3 +0,0 @@
export * from './reflect';
export * from './stereotype';
export * from './types';

View File

@ -1,2 +0,0 @@
export const POUCH_INJECTABLE_DEFINITION = 'loafer:pouch/injectable_definition';
export const POUCH_INJECT_DEFINITION = 'loafer:pouch/inject_definition';

View File

@ -1,12 +0,0 @@
export enum InjectableSterotype {
INJECTABLE = 'Injectable',
APP = 'App',
CONFIGURATION = 'Configuration',
SERVICE = 'Service',
}
export enum InjectSterotype {
INJECT = 'Inject',
VALUE = 'Value',
}

View File

@ -1,121 +0,0 @@
import {
ClassType,
DecoratorType,
DESIGN_PARAMTYPES,
DESIGN_TYPE,
PropertyType,
} from '@loafer/core/constants';
import { InjectSterotype } from '@loafer/pouches/constants';
import { validateQualifier } from '@loafer/pouches/util/qualifier';
import InjectConfig from '@loafer/pouches/decorator/InjectConfig';
export interface InjectItem {
stereotype: InjectSterotype;
decoratorType: DecoratorType;
propertyConfig?: InjectConfig;
parameterConfigMap?: Map<number, InjectConfig>;
}
class InjectDefinition {
protected clazz: ClassType;
protected injectMap: Map<PropertyType, InjectItem>;
public constructor(clazz: ClassType) {
this.clazz = clazz;
this.injectMap = new Map();
}
public get injectors(): Map<PropertyType, InjectItem> {
return this.injectMap;
}
/**
* addInject
*/
public addInject(injectConfig: InjectConfig, propertyKey: PropertyType, parameterIndex?: number): void {
injectConfig.qualifier = validateQualifier(this.clazz, injectConfig.qualifier);
if (undefined === injectConfig.required) {
injectConfig.required = false;
}
if(typeof parameterIndex === 'number') {
this.addInjectParameter(injectConfig, propertyKey, parameterIndex);
} else {
this.addInjectProperty(injectConfig, propertyKey);
}
}
/**
* addValue
*/
public addValue(value: string, propertyKey: PropertyType, parameterIndex?: number): void {
if(typeof parameterIndex === 'number') {
this.addValueParameter(value, propertyKey, parameterIndex);
} else {
this.addValueProperty(value, propertyKey);
}
}
private addValueProperty(value: string, propertyKey: PropertyType): void {
return;
}
private addValueParameter(value: string, propertyKey: PropertyType, parameterIndex: number): void {
return;
}
private addInjectParameter(injectConfig: InjectConfig,
propertyKey: PropertyType, parameterIndex: number): void {
let injectItem: InjectItem;
let parameterTypes: any[] = Reflect.getMetadata(DESIGN_PARAMTYPES, this.clazz, propertyKey);
if (undefined === injectConfig.clazz) {
injectConfig.clazz = parameterTypes[parameterIndex];
}
if (this.injectMap.has(propertyKey)) {
injectItem = this.injectMap.get(propertyKey);
} else {
injectItem = {
stereotype: InjectSterotype.INJECT,
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: PropertyType): void {
if (this.injectMap.has(propertyKey)) {
throw new Error(`Cannot apply @inject decorator on one property[${propertyKey}] multiple times.`);
}
let propertyType: any = Reflect.getMetadata(DESIGN_TYPE, this.clazz, propertyKey);
if (undefined === injectConfig.clazz) {
injectConfig.clazz = propertyType;
}
let injectItem: InjectItem = {
stereotype: InjectSterotype.INJECT,
decoratorType: DecoratorType.PROPERTY,
propertyConfig: injectConfig,
};
this.injectMap.set(propertyKey, injectItem);
}
}
export default InjectDefinition;

View File

@ -1,76 +0,0 @@
import { ClassType, PropertyType } from '@loafer/core/constants';
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
import { InjectableSterotype, PouchScope } from '@loafer/pouches/constants';
class InjectableDefinition implements PouchDefinition {
protected _clazz: ClassType;
protected _stereotype: InjectableSterotype;
protected _scope: PouchScope = PouchScope.SINGLETON;
protected _qualifier: PropertyType = undefined;
protected _postConstruct: Set<string> = undefined;
protected _preDestroy: Set<string> = undefined;
public constructor(clazz: ClassType) {
this._clazz = clazz;
this._stereotype = InjectableSterotype.INJECTABLE;
}
public get Clazz(): ClassType {
return this._clazz;
}
public get Stereotype(): InjectableSterotype {
return this._stereotype;
}
public set Stereotype(stereotype: InjectableSterotype) {
this._stereotype = stereotype;
}
public get Scope(): PouchScope {
return this._scope;
}
public set Scope(scope: PouchScope) {
this._scope = scope;
}
public get Qualifier(): PropertyType {
return this._qualifier;
}
public set Qualifier(qualifier: PropertyType) {
this._qualifier = qualifier;
}
public get PostConstruct(): Set<string> {
return this._postConstruct;
}
public addPostConstruct(postConstruct: string): void {
if (undefined === this._postConstruct) {
this._postConstruct = new Set();
}
this._postConstruct.add(postConstruct);
}
public get PreDestroy(): Set<string> {
return this._preDestroy;
}
public addPreDestroy(preDestroy: string): void {
if (undefined === this._preDestroy) {
this._preDestroy = new Set();
}
this._preDestroy.add(preDestroy);
}
public isSingleton(): boolean {
return this._scope === PouchScope.SINGLETON;
}
public isTransient(): boolean {
return this._scope === PouchScope.TRANSIENT;
}
}
export default InjectableDefinition;

View File

@ -1,7 +1,7 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants';
} from '@loafer/core/constants/types';
interface PouchFactory {
/**

View File

@ -1,9 +1,14 @@
import { ClassType, PropertyType } from '@loafer/core/constants';
import { InjectableSterotype, PouchScope } from '@loafer/pouches/constants';
import {
ClassType,
PropertyType,
} from '@loafer/core/constants/types';
import {
PouchScope,
} from '@loafer/pouches/constants/types';
interface PouchDefinition {
readonly Clazz: ClassType;
Stereotype: InjectableSterotype;
Scope: PouchScope;
Qualifier: PropertyType;
readonly PostConstruct: Set<string>;

View File

@ -1,7 +1,7 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants';
} from '@loafer/core/constants/types';
interface SingletonPouchRegistry {
registerSingleton(pouch: any, qualifier?: PropertyType): void;

View File

@ -1,15 +1,7 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants';
import {
InjectableSterotype,
} from '@loafer/pouches/constants';
import {
validateQualifier,
} from '@loafer/pouches/util/qualifier';
} from '@loafer/core/constants/types';
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';
import PouchDefinitionRegistry from '@loafer/pouches/factory/registry/PouchDefinitionRegistry';
@ -19,27 +11,25 @@ import DefaultSingletonPouchRegistry from '@loafer/pouches/factory/implement/Def
abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implements PouchDefinitionRegistry {
protected pouchDefinitionMap: Map<PropertyType, Map<ClassType, PouchDefinition>>;
protected pouchDefinitionStereotypeMap: Map<InjectableSterotype, Map<ClassType, PouchDefinition>>;
public constructor() {
super();
this.pouchDefinitionMap = new Map();
this.pouchDefinitionStereotypeMap = new Map();
}
public registerPouchDefinition(pouchDefinition: PouchDefinition): void {
let clazz = pouchDefinition.Clazz;
let qualifier = validateQualifier(clazz, pouchDefinition.Qualifier);
// let qualifier = validateQualifier(clazz, pouchDefinition.Qualifier);
if (this.hasPouchDefinition(qualifier, clazz)) {
throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is exist already`);
}
let map = this.pouchDefinitionMap.get(qualifier);
if (undefined === map) {
map = new Map();
this.pouchDefinitionMap.set(qualifier, map);
}
map.set(clazz, pouchDefinition);
// if (this.hasPouchDefinition(qualifier, clazz)) {
// throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is exist already`);
// }
// let map = this.pouchDefinitionMap.get(qualifier);
// if (undefined === map) {
// map = new Map();
// this.pouchDefinitionMap.set(qualifier, map);
// }
// map.set(clazz, pouchDefinition);
}
public getPouchDefinition(qualifier: PropertyType, clazz?: ClassType): PouchDefinition {
@ -58,8 +48,8 @@ abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implem
}
public getPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): PouchDefinition {
const _qualifier = validateQualifier(clazz, qualifier);
return this.getPouchDefinition(_qualifier, clazz);
// const _qualifier = validateQualifier(clazz, qualifier);
return this.getPouchDefinition(qualifier, clazz);
}
@ -67,9 +57,9 @@ abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implem
return undefined === this.getPouchDefinition(qualifier, clazz) ? false : true;
}
public hasPouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): boolean {
const _qualifier = validateQualifier(clazz, qualifier);
// const _qualifier = validateQualifier(clazz, qualifier);
return this.hasPouchDefinition(_qualifier, clazz);
return this.hasPouchDefinition(qualifier, clazz);
}
public removePouchDefinition(qualifier: PropertyType, clazz?: ClassType): void {
@ -85,8 +75,8 @@ abstract class AbstractPouchFactory extends DefaultSingletonPouchRegistry implem
}
public removePouchDefinitionByClass(clazz: ClassType, qualifier?: PropertyType): void {
const _qualifier = validateQualifier(clazz, qualifier);
this.removePouchDefinition(_qualifier, clazz);
// const _qualifier = validateQualifier(clazz, qualifier);
// this.removePouchDefinition(_qualifier, clazz);
}

View File

@ -1,28 +1,11 @@
import {
ClassType,
DecoratorType,
PropertyType,
} from '@loafer/core/constants';
} from '@loafer/core/constants/types';
import {
PouchScope,
POUCH_INJECT_DEFINITION,
POUCH_INJECTABLE_DEFINITION,
} from '@loafer/pouches/constants';
import {
validateQualifier,
} from '@loafer/pouches/util/qualifier';
import InjectConfig from '@loafer/pouches/decorator/InjectConfig';
import InjectDefinition, {
InjectItem,
} from '@loafer/pouches/definition/InjectDefinition';
import InjectableDefinition from '@loafer/pouches/definition/InjectableDefinition';
} from '@loafer/pouches/constants/types';
import PouchFactory from '@loafer/pouches/factory/PouchFactory';
import AbstractPouchFactory from '@loafer/pouches/factory/implement/AbstractPouchFactory';
@ -42,21 +25,21 @@ class DefaultPouchFactory extends AbstractPouchFactory implements PouchFactory,
return this._getPouch(pouchDefinition, ...args);
}
public getPouchByClass(clazz: ClassType, qualifier: PropertyType, ...args: any[]): any {
let _qualifier = validateQualifier(clazz, qualifier);
// let _qualifier = validateQualifier(clazz, qualifier);
let pouchDefinition = this._getPouchDefinition(_qualifier, clazz);
if (undefined === pouchDefinition) {
throw new Error(`This class[${clazz.constructor.name}:${qualifier}] is not pouch.`);
}
// let pouchDefinition = this._getPouchDefinition(_qualifier, clazz);
// if (undefined === pouchDefinition) {
// throw new Error(`This class[${clazz.constructor.name}:${qualifier}] is not pouch.`);
// }
return this._getPouch(pouchDefinition, ...args);
// return this._getPouch(pouchDefinition, ...args);
}
private _getPouchDefinition(qualifier: PropertyType, clazz: ClassType): PouchDefinition {
let pouchDefinition = this.getPouchDefinition(qualifier, clazz);
if (undefined === pouchDefinition) {
pouchDefinition = this._getInjectableDefinition(clazz);
// pouchDefinition = this._getInjectableDefinition(clazz);
if (undefined !== pouchDefinition) {
this.registerPouchDefinition(pouchDefinition);
}
@ -84,49 +67,49 @@ class DefaultPouchFactory extends AbstractPouchFactory implements PouchFactory,
return;
}
let injectDefinition: InjectDefinition = this._getInjectDefinition(clazz);
if (undefined !== injectDefinition) {
let injectors: Map<PropertyType, InjectItem> = injectDefinition.injectors;
let propertyDescriptor: PropertyDescriptor;
injectors.forEach((injectItem, key, map) => {
propertyDescriptor = Object.getOwnPropertyDescriptor(clazz, key);
// let injectDefinition: InjectDefinition = this._getInjectDefinition(clazz);
// if (undefined !== injectDefinition) {
// let injectors: Map<PropertyType, InjectItem> = injectDefinition.injectors;
// let propertyDescriptor: PropertyDescriptor;
// injectors.forEach((injectItem, key, map) => {
// propertyDescriptor = Object.getOwnPropertyDescriptor(clazz, key);
switch (injectItem.decoratorType) {
case DecoratorType.PROPERTY:
this._injectDependencyProperty(instance, clazz, key, propertyDescriptor, injectItem.propertyConfig);
break;
case DecoratorType.PARAMETER:
this._injectDependencyParameter(instance, propertyDescriptor, injectItem.parameterConfigMap);
break;
default:
break;
}
});
}
this._injectDependency(instance, Object.getPrototypeOf(clazz));
// switch (injectItem.decoratorType) {
// case DecoratorType.PROPERTY:
// this._injectDependencyProperty(instance, clazz, key, propertyDescriptor, injectItem.propertyConfig);
// break;
// case DecoratorType.PARAMETER:
// this._injectDependencyParameter(instance, propertyDescriptor, injectItem.parameterConfigMap);
// break;
// default:
// break;
// }
// });
// }
// this._injectDependency(instance, Object.getPrototypeOf(clazz));
}
private _injectDependencyProperty(instance: any, clazz: ClassType, propertyKey: PropertyType,
propertyDescriptor: PropertyDescriptor, injectConfig: InjectConfig): void {
let pouch = this.getPouchByClass(injectConfig.clazz, injectConfig.qualifier);
if (injectConfig.required && undefined === instance) {
throw new Error(`Pouch which used by [${clazz.constructor.name}.${propertyKey}] is not exist in the context.`);
}
instance[propertyKey] = pouch;
}
// private _injectDependencyProperty(instance: any, clazz: ClassType, propertyKey: PropertyType,
// propertyDescriptor: PropertyDescriptor, injectConfig: InjectConfig): void {
// let pouch = this.getPouchByClass(injectConfig.clazz, injectConfig.qualifier);
// if (injectConfig.required && undefined === instance) {
// throw new Error(`Pouch which used by [${clazz.constructor.name}.${propertyKey}] is not exist in the context.`);
// }
// instance[propertyKey] = pouch;
// }
private _injectDependencyParameter(target: object, propertyDescriptor: PropertyDescriptor,
parameterConfigs: Map<number, InjectConfig>): void {
console.log('');
}
// private _injectDependencyParameter(target: object, propertyDescriptor: PropertyDescriptor,
// parameterConfigs: Map<number, InjectConfig>): void {
// console.log('');
// }
private _getInjectableDefinition(clazz: ClassType): InjectableDefinition {
return Reflect.getMetadata(POUCH_INJECTABLE_DEFINITION, clazz);
}
// private _getInjectableDefinition(clazz: ClassType): InjectableDefinition {
// return Reflect.getMetadata(POUCH_INJECTABLE_DEFINITION, clazz);
// }
private _getInjectDefinition(clazz: ClassType): InjectDefinition {
return Reflect.getMetadata(POUCH_INJECT_DEFINITION, clazz);
}
// private _getInjectDefinition(clazz: ClassType): InjectDefinition {
// return Reflect.getMetadata(POUCH_INJECT_DEFINITION, clazz);
// }
}
export default DefaultPouchFactory;

View File

@ -1,14 +1,10 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants';
} from '@loafer/core/constants/types';
import SingletonPouchRegistry from '@loafer/pouches/factory/config/SingletonPouchRegistry';
import {
validateQualifier,
} from '@loafer/pouches/util/qualifier';
class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
protected singletonInstanceMap: Map<PropertyType, Map<ClassType, any>>;
@ -18,32 +14,32 @@ class DefaultSingletonPouchRegistry implements SingletonPouchRegistry {
public registerSingleton(pouch: any, qualifier?: PropertyType): void {
let clazz: ClassType = Object.getPrototypeOf(pouch);
const _qualifier = validateQualifier(clazz, qualifier);
// const _qualifier = validateQualifier(clazz, qualifier);
if (this._hasSingleton(_qualifier, clazz)) {
throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is exist already`);
}
let map = this.singletonInstanceMap.get(_qualifier);
if (undefined === map) {
map = new Map();
this.singletonInstanceMap.set(_qualifier, map);
}
map.set(clazz, pouch);
// if (this._hasSingleton(_qualifier, clazz)) {
// throw new Error(`Pouch Definition[${clazz.constructor.name}:${qualifier}] is exist already`);
// }
// let map = this.singletonInstanceMap.get(_qualifier);
// if (undefined === map) {
// map = new Map();
// this.singletonInstanceMap.set(_qualifier, map);
// }
// map.set(clazz, pouch);
}
public getSingleton(qualifier: PropertyType, clazz?: ClassType): any {
return this._getSingleton(qualifier, clazz);
}
public getSingletonByClass(clazz: ClassType, qualifier?: PropertyType): any {
const _qualifier = validateQualifier(clazz, qualifier);
return this._getSingleton(_qualifier, clazz);
// 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);
// const _qualifier = validateQualifier(clazz, qualifier);
return this._hasSingleton(qualifier, clazz);
}

View File

@ -1,7 +1,7 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants';
} from '@loafer/core/constants/types';
import PouchDefinition from '@loafer/pouches/factory/config/PouchDefinition';

View File

@ -1,8 +0,0 @@
import {
ClassType,
PropertyType,
} from '@loafer/core/constants';
export const validateQualifier = (clazz: ClassType, qualifier: PropertyType) => {
return undefined === qualifier ? clazz.constructor.name : qualifier;
};

View File

@ -47,7 +47,6 @@ import Platform from '@overflow/commons/platform';
import App from '@loafer/context/decorator/App';
import Inject from '@loafer/pouches/decorator/Inject';
import AppContext from '@loafer/context/AppContext';
import GetAppContext from '@loafer/context';
import * as AppContextLifecycleActions from '@loafer/context/redux/action/lifecycle';
import WebSocketRPC from '@overflow/commons/websocket/WebSocketRPC';
@ -99,7 +98,6 @@ class OFApplication implements ApplicationStater {
this.container = await Platform.getAppContainer(this.config.container.placeholderID);
this.displayLoading();
this.context = await this.initContext();
this.rpcClient = await this.initRpcClient();
// this.context.PouchFactory.registerPouch(this.rpcClient);
@ -114,15 +112,6 @@ class OFApplication implements ApplicationStater {
}
}
private initContext(): Promise<AppContext> {
const appContext = new Promise<AppContext>(resolve => {
const context = GetAppContext();
resolve(context);
});
return appContext;
}
private initRpcClient(): Promise<WebSocketRPC> {
const rpcClient = new Promise<WebSocketRPC>((resolve, reject) => {
let client = new WebSocketRPC(this.config.rpc.url);

View File

@ -1,7 +1,6 @@
import { SagaIterator } from 'redux-saga';
import { call, Effect, fork, put, takeEvery } from 'redux-saga/effects';
import GetAppContext from '@loafer/context';
import AppContext from '@loafer/context/AppContext';
import { SagaWatcher } from '@overflow/commons/constant';
import Action from '@overflow/commons/redux/Action';
@ -19,10 +18,10 @@ function* request(action: Action<AsyncRequestPayload>): SagaIterator {
// type: types.SENDING_REQUEST,
// payload: {sendingRequest: true},
// });`${service}.${method}`
let webSocketRPC: WebSocketRPC = GetAppContext().getPouchByClass(WebSocketRPC.prototype, undefined);
let result = yield call({context: webSocketRPC, fn: webSocketRPC.Call}, `${service}.${method}`, args);
// let webSocketRPC: WebSocketRPC = GetAppContext().getPouchByClass(WebSocketRPC.prototype, undefined);
// let result = yield call({context: webSocketRPC, fn: webSocketRPC.Call}, `${service}.${method}`, args);
yield put(AsyncRequestActions.requestSuccess(requestType, result));
// yield put(AsyncRequestActions.requestSuccess(requestType, result));
} catch (e) {
yield put(AsyncRequestActions.requestFailure(requestType, e));
} finally {