ing
This commit is contained in:
parent
b3189213e5
commit
046ea0e6f2
|
@ -2,7 +2,7 @@ import {
|
||||||
Class,
|
Class,
|
||||||
Method,
|
Method,
|
||||||
} from '@overflow/commons/core/reflect';
|
} from '@overflow/commons/core/reflect';
|
||||||
import { ClassType } from '@overflow/commons/core/type';
|
import { ClassType, PropertyKeyType } from '@overflow/commons/core/type';
|
||||||
import { ApplicationContext } from './context';
|
import { ApplicationContext } from './context';
|
||||||
import {
|
import {
|
||||||
ConfigurationAnnotation,
|
ConfigurationAnnotation,
|
||||||
|
@ -32,36 +32,34 @@ export class Application {
|
||||||
*/
|
*/
|
||||||
public async run(): Promise<ApplicationContext> {
|
public async run(): Promise<ApplicationContext> {
|
||||||
let runner = this.findRunner();
|
let runner = this.findRunner();
|
||||||
if (null === runner) {
|
if (undefined === runner) {
|
||||||
throw new Error(`There is not exist @Runner on Application[${this._primaryClass.name}]`);
|
throw new Error(`There is not exist @Runner on Application[${this._primaryClass.name}]`);
|
||||||
}
|
}
|
||||||
let instanceFactory = this._applicationContext.instanceFactory;
|
let instanceFactory = this._applicationContext.instanceFactory;
|
||||||
let instance = instanceFactory.getInstance(null, this._primaryClass);
|
|
||||||
|
let clazz: Class = Class.forClass(this._primaryClass);
|
||||||
|
let instance = clazz.getConstructor().newInstance();
|
||||||
|
instanceFactory.applyInstance(this._primaryClass, instance);
|
||||||
|
|
||||||
await runner.invoke(instance);
|
await runner.invoke(instance);
|
||||||
|
|
||||||
return this._applicationContext;
|
return this._applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private findRunner(): Method {
|
private findRunner(): Method | undefined {
|
||||||
let clazz: Class = Class.forClass(this._primaryClass);
|
let clazz: Class = Class.forClass(this._primaryClass);
|
||||||
let methods = clazz.getOwnMethods();
|
let methods = clazz.getOwnMethods();
|
||||||
if (null === methods || 0 === methods.size) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const key in methods.keys()) {
|
for (let key of Array.from(methods.keys())) {
|
||||||
if (methods.hasOwnProperty(key)) {
|
let method = methods.get(key);
|
||||||
const method = methods[key];
|
let runnerAnnotation = method.getOwnAnnotation(RunnerAnnotation);
|
||||||
let runnerAnnotation = method.getOwnAnnotation(RunnerAnnotation);
|
if (undefined === runnerAnnotation) {
|
||||||
if (undefined === runnerAnnotation) {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return method;
|
|
||||||
}
|
}
|
||||||
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createContext(): ApplicationContext {
|
private createContext(): ApplicationContext {
|
||||||
|
@ -105,7 +103,8 @@ export class Application {
|
||||||
if (null === methods) {
|
if (null === methods) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let instance = instanceFactory.getInstance(null, configurationType);
|
let instance = clazz.getConstructor().newInstance();
|
||||||
|
instanceFactory.applyInstance(configurationType, instance);
|
||||||
methods.forEach(method => {
|
methods.forEach(method => {
|
||||||
let instanceAnnotation = method.getOwnAnnotation(InstanceAnnotation);
|
let instanceAnnotation = method.getOwnAnnotation(InstanceAnnotation);
|
||||||
if (undefined === instanceAnnotation) {
|
if (undefined === instanceAnnotation) {
|
||||||
|
|
|
@ -52,7 +52,6 @@ export class Class extends AccessibleObject {
|
||||||
this._clazzType = clazzType;
|
this._clazzType = clazzType;
|
||||||
this._fields = new Map();
|
this._fields = new Map();
|
||||||
this._methods = new Map();
|
this._methods = new Map();
|
||||||
this._constructor = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,6 +95,9 @@ export class Class extends AccessibleObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getConstructor(): Constructor {
|
public getConstructor(): Constructor {
|
||||||
|
if (undefined === this._constructor) {
|
||||||
|
this._constructor = new Constructor(this, undefined);
|
||||||
|
}
|
||||||
return this._constructor;
|
return this._constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {Executable} from './executable';
|
||||||
export class Constructor extends Executable {
|
export class Constructor extends Executable {
|
||||||
private _rawConstructor: Function;
|
private _rawConstructor: Function;
|
||||||
|
|
||||||
public constructor(declaringClazz: Class, parameterTypes: any[]) {
|
public constructor(declaringClazz: Class, parameterTypes?: any[]) {
|
||||||
super(declaringClazz, CONSTRUCTOR_NAME, parameterTypes);
|
super(declaringClazz, CONSTRUCTOR_NAME, parameterTypes);
|
||||||
this._rawConstructor = TypeUtil.getPrototype(declaringClazz.getType())[CONSTRUCTOR_NAME];
|
this._rawConstructor = TypeUtil.getPrototype(declaringClazz.getType())[CONSTRUCTOR_NAME];
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ export abstract class Executable extends AccessibleObject implements Member {
|
||||||
private _name: PropertyKeyType;
|
private _name: PropertyKeyType;
|
||||||
private _parameters: Parameter[];
|
private _parameters: Parameter[];
|
||||||
|
|
||||||
protected constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes: any[]) {
|
protected constructor(declaringClazz: Class, name: PropertyKeyType, parameterTypes?: any[]) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._clazz = declaringClazz;
|
this._clazz = declaringClazz;
|
||||||
this._name = name;
|
this._name = name;
|
||||||
|
|
||||||
if (null === parameterTypes) {
|
if (undefined === parameterTypes) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
} from '@overflow/commons/di/type';
|
} from '@overflow/commons/di/type';
|
||||||
|
|
||||||
export interface InjectAnnotationAttributes {
|
export interface InjectAnnotationAttributes {
|
||||||
name?: InstanceNameType[];
|
name?: InstanceNameType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InjectAnnotation implements Annotation {
|
export class InjectAnnotation implements Annotation {
|
||||||
|
@ -29,11 +29,7 @@ export class InjectAnnotation implements Annotation {
|
||||||
|
|
||||||
if (TypeUtil.isString(name)) {
|
if (TypeUtil.isString(name)) {
|
||||||
this.attributes = {
|
this.attributes = {
|
||||||
name: [<InstanceNameType>name],
|
name: <InstanceNameType>name,
|
||||||
};
|
|
||||||
} else if (TypeUtil.isArray(name)) {
|
|
||||||
this.attributes = {
|
|
||||||
name: <InstanceNameType[]>name,
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this.attributes = <InjectAnnotationAttributes>name;
|
this.attributes = <InjectAnnotationAttributes>name;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
} from '@overflow/commons/di/type';
|
} from '@overflow/commons/di/type';
|
||||||
|
|
||||||
export interface ResourceAnnotationAttributes {
|
export interface ResourceAnnotationAttributes {
|
||||||
name: InstanceNameType[];
|
name?: InstanceNameType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ResourceAnnotation implements Annotation {
|
export class ResourceAnnotation implements Annotation {
|
||||||
|
@ -22,12 +22,14 @@ export class ResourceAnnotation implements Annotation {
|
||||||
public constructor(name: InstanceNameType | ResourceAnnotationAttributes) {
|
public constructor(name: InstanceNameType | ResourceAnnotationAttributes) {
|
||||||
|
|
||||||
if (undefined === name) {
|
if (undefined === name) {
|
||||||
throw new Error(`name attribute must be specified.`);
|
this.attributes = {
|
||||||
|
};
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TypeUtil.isString(name)) {
|
if (TypeUtil.isString(name)) {
|
||||||
this.attributes = {
|
this.attributes = {
|
||||||
name: [<InstanceNameType>name],
|
name: <InstanceNameType>name,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
this.attributes = <ResourceAnnotationAttributes>name;
|
this.attributes = <ResourceAnnotationAttributes>name;
|
||||||
|
|
|
@ -1,27 +1,35 @@
|
||||||
import {
|
import {
|
||||||
ClassType,
|
ClassType, PropertyKeyType,
|
||||||
} from '@overflow/commons/core/type';
|
} from '@overflow/commons/core/type';
|
||||||
|
import {
|
||||||
|
Class, Annotation, Field,
|
||||||
|
} from '@overflow/commons/core/reflect';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ValueAnnotation, InjectAnnotation, ResourceAnnotation,
|
||||||
|
} from '@overflow/commons/di/decorators';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
InstanceNameType,
|
InstanceNameType,
|
||||||
InstanceFactoryType,
|
InstanceFactoryType,
|
||||||
} from '@overflow/commons/di/type';
|
} from '@overflow/commons/di/type';
|
||||||
|
|
||||||
|
|
||||||
import {InstanceDefinitionRegistry} from './instance_definition_registry';
|
import {InstanceDefinitionRegistry} from './instance_definition_registry';
|
||||||
import {InstanceDefinition} from './instance_definition';
|
import {InstanceDefinition} from './instance_definition';
|
||||||
|
|
||||||
export class InstanceFactory implements InstanceDefinitionRegistry {
|
export class InstanceFactory implements InstanceDefinitionRegistry {
|
||||||
private singletonObjects: Map<InstanceNameType, any> = new Map();
|
private _singletonObjects: Map<InstanceNameType, any> = new Map();
|
||||||
private singletonFactories: Map<InstanceNameType, InstanceFactoryType> = new Map();
|
private _singletonFactories: Map<InstanceNameType, InstanceFactoryType> = new Map();
|
||||||
private instanceDefinitionMap: Map<InstanceNameType, InstanceDefinition> = new Map();
|
private _instanceDefinitionMap: Map<InstanceNameType, InstanceDefinition> = new Map();
|
||||||
private instanceDefinitionNames: Set<InstanceNameType> = new Set();
|
private _instanceDefinitionNames: Set<InstanceNameType> = new Set();
|
||||||
|
private _values: any;
|
||||||
/**
|
/**
|
||||||
* getInstance
|
* getInstance
|
||||||
*/
|
*/
|
||||||
public getInstance(name: InstanceNameType, requiredType: ClassType, ...args: any[]): any {
|
public getInstance(name: InstanceNameType, requiredType: ClassType, ...args: any[]): any | undefined {
|
||||||
if (null === name) {
|
if (null === name) {
|
||||||
return this.getInstanceByType(requiredType);
|
name = requiredType.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
let sharedInstance = this.getSingleton(name);
|
let sharedInstance = this.getSingleton(name);
|
||||||
|
@ -29,20 +37,74 @@ export class InstanceFactory implements InstanceDefinitionRegistry {
|
||||||
return sharedInstance;
|
return sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let instanceDefinition = this.getInstanceDefinition(name);
|
||||||
|
let clazzType = instanceDefinition.instanceClass;
|
||||||
|
let clazz = Class.forClass(clazzType);
|
||||||
|
if (undefined === clazz) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let ctor = clazz.getConstructor();
|
||||||
|
let ctorParams = ctor.getParameters();
|
||||||
|
let ctorArgs = [];
|
||||||
|
if (0 < ctorParams.length) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
let instance = ctor.newInstance(ctorArgs);
|
||||||
|
|
||||||
|
this.applyInstance(clazzType, instance);
|
||||||
|
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getInstanceByName(requiredType: ClassType): any {
|
private getInstanceByName(requiredType: ClassType): any | undefined {
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getInstanceByType(requiredType: ClassType): any {
|
private getInstanceByType(requiredType: ClassType): any | undefined {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* applyInstance
|
||||||
|
*/
|
||||||
|
public applyInstance(clazzType: ClassType, instance: any): void {
|
||||||
|
let clazz: Class = Class.forClass(clazzType);
|
||||||
|
|
||||||
|
let fields = clazz.getFields();
|
||||||
|
|
||||||
|
fields.forEach((field: Field, key: PropertyKeyType, map: Map<PropertyKeyType, Field>): void => {
|
||||||
|
let fieldAnnotations = field.getAnnotations();
|
||||||
|
fieldAnnotations.forEach((value: Annotation, annonType: ClassType, annonMap: Map<ClassType, Annotation>): void => {
|
||||||
|
switch (annonType) {
|
||||||
|
case ValueAnnotation:
|
||||||
|
{
|
||||||
|
let annon = <ValueAnnotation>value;
|
||||||
|
instance[field.getName()] = this.getValue(annon.attributes.value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case InjectAnnotation:
|
||||||
|
{
|
||||||
|
let annon = <InjectAnnotation>value;
|
||||||
|
instance[field.getName()] = this.getInstance(annon.attributes.name, field.getType());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ResourceAnnotation:
|
||||||
|
{
|
||||||
|
let annon = <ResourceAnnotation>value;
|
||||||
|
instance[field.getName()] = this.getSingleton(annon.attributes.name || field.getName());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSingleton(name: InstanceNameType): any | undefined {
|
private getSingleton(name: InstanceNameType): any | undefined {
|
||||||
let singletonObject = this.singletonObjects.get(name);
|
let singletonObject = this._singletonObjects.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,44 +115,56 @@ export class InstanceFactory implements InstanceDefinitionRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerJSON(json: any): void {
|
public registerJSON(json: any): void {
|
||||||
//
|
this._values = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getValue
|
||||||
|
*/
|
||||||
|
public getValue(keyPath: string): any {
|
||||||
|
let paths = keyPath.split('.');
|
||||||
|
let result = this._values;
|
||||||
|
for (let i = 0, len = paths.length; i < len; i++) {
|
||||||
|
result = result[paths[i]];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerSingleton(name: InstanceNameType, instanceType: any, instance: any): void {
|
public registerSingleton(name: InstanceNameType, instanceType: any, instance: any): void {
|
||||||
//
|
this._singletonObjects.set(name, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerInstanceDefinition(name: InstanceNameType, instanceDefinition: InstanceDefinition): void {
|
public registerInstanceDefinition(name: InstanceNameType, instanceDefinition: InstanceDefinition): void {
|
||||||
let oldInstanceDefinition = this.instanceDefinitionMap.get(name);
|
let oldInstanceDefinition = this._instanceDefinitionMap.get(name);
|
||||||
if (undefined !== oldInstanceDefinition) {
|
if (undefined !== oldInstanceDefinition) {
|
||||||
throw new Error(`InstanceDefinition[${name}] is already exist.`);
|
throw new Error(`InstanceDefinition[${name}] is already exist.`);
|
||||||
}
|
}
|
||||||
this.instanceDefinitionNames.add(name);
|
this._instanceDefinitionNames.add(name);
|
||||||
this.instanceDefinitionMap.set(name, instanceDefinition);
|
this._instanceDefinitionMap.set(name, instanceDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeInstanceDefinition(name: InstanceNameType): void {
|
public removeInstanceDefinition(name: InstanceNameType): void {
|
||||||
if (!this.instanceDefinitionMap.has(name)) {
|
if (!this._instanceDefinitionMap.has(name)) {
|
||||||
throw new Error(`InstanceDefinition[${name}] is not exist.`);
|
throw new Error(`InstanceDefinition[${name}] is not exist.`);
|
||||||
}
|
}
|
||||||
this.instanceDefinitionNames.delete(name);
|
this._instanceDefinitionNames.delete(name);
|
||||||
this.instanceDefinitionMap.delete(name);
|
this._instanceDefinitionMap.delete(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getInstanceDefinition(name: InstanceNameType): InstanceDefinition | undefined {
|
public getInstanceDefinition(name: InstanceNameType): InstanceDefinition | undefined {
|
||||||
return this.instanceDefinitionMap.get(name);
|
return this._instanceDefinitionMap.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public containsInstanceDefinition(name: InstanceNameType): boolean {
|
public containsInstanceDefinition(name: InstanceNameType): boolean {
|
||||||
return this.instanceDefinitionMap.has(name);
|
return this._instanceDefinitionMap.has(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getInstanceDefinitionNames(): Set<InstanceNameType> {
|
public getInstanceDefinitionNames(): Set<InstanceNameType> {
|
||||||
return this.instanceDefinitionNames;
|
return this._instanceDefinitionNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getInstanceDefinitionCount(): number {
|
public getInstanceDefinitionCount(): number {
|
||||||
return this.instanceDefinitionMap.size;
|
return this._instanceDefinitionMap.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public isInstanceNameInUse(name: InstanceNameType): boolean {
|
public isInstanceNameInUse(name: InstanceNameType): boolean {
|
||||||
|
|
|
@ -83,7 +83,7 @@ class WebAppApplication extends B {
|
||||||
private htmlContainerID: string;
|
private htmlContainerID: string;
|
||||||
private container: HTMLElement;
|
private container: HTMLElement;
|
||||||
|
|
||||||
@Inject()
|
@Resource()
|
||||||
private store: Store<any>;
|
private store: Store<any>;
|
||||||
private history: History;
|
private history: History;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user