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