ing
This commit is contained in:
parent
606d7b0e82
commit
61fb53a49c
|
@ -12,45 +12,69 @@ import {
|
|||
RunnerAnnotation,
|
||||
WebApplicationAnnotation,
|
||||
} from './decorators';
|
||||
import { InstanceDefinition } from '@overflow/commons/di/factory';
|
||||
|
||||
export class Application {
|
||||
private _primaryClass: ClassType;
|
||||
private _appClass: Class;
|
||||
private _appAnnotation: WebApplicationAnnotation;
|
||||
private _applicationContext: ApplicationContext;
|
||||
|
||||
public static async run(primaryClass: ClassType): Promise<ApplicationContext> {
|
||||
let app: Application = new Application(primaryClass);
|
||||
return app.run();
|
||||
public constructor(primaryClass: ClassType) {
|
||||
this.initialize(primaryClass);
|
||||
}
|
||||
|
||||
public constructor(primaryClass: ClassType) {
|
||||
this._primaryClass = primaryClass;
|
||||
private initialize(primaryClass: ClassType): void {
|
||||
let clazz: Class = Class.forClassType(primaryClass);
|
||||
|
||||
this.createContext();
|
||||
let wa: WebApplicationAnnotation = clazz.getOwnAnnotation(WebApplicationAnnotation);
|
||||
if (undefined === wa) {
|
||||
throw new Error(`Class is not WebApplication type. add @WebApplication annotation to class[${primaryClass.name}]`);
|
||||
}
|
||||
|
||||
this._appClass = clazz;
|
||||
this._appAnnotation = wa;
|
||||
}
|
||||
|
||||
public static async run(primaryClass: ClassType): Promise<ApplicationContext> {
|
||||
return new Application(primaryClass).run();
|
||||
}
|
||||
|
||||
/**
|
||||
* run
|
||||
*/
|
||||
public run(): ApplicationContext {
|
||||
this._applicationContext = new ApplicationContext();
|
||||
|
||||
let injectables: ClassType[] = this.getInjectables();
|
||||
this._applicationContext.instanceDefinitionReader.registerInjectables(...injectables);
|
||||
|
||||
let runner = this.findRunner();
|
||||
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._appClass.getName()}]`);
|
||||
}
|
||||
let instanceFactory = this._applicationContext.instanceFactory;
|
||||
|
||||
let clazz: Class = Class.forClassType(this._primaryClass);
|
||||
let instance = clazz.getConstructor().newInstance();
|
||||
instanceFactory.applyInstance(this._primaryClass, instance);
|
||||
let instance = instanceFactory.getInstance();
|
||||
|
||||
runner.invoke(instance);
|
||||
|
||||
return this._applicationContext;
|
||||
}
|
||||
|
||||
private getInjectables(): ClassType[] {
|
||||
let injectables: Set<ClassType> = new Set();
|
||||
injectables.add(this._appClass.getType());
|
||||
this._appAnnotation.attributes.injectables.forEach(injectableType => {
|
||||
injectables.add(injectableType);
|
||||
});
|
||||
this._appAnnotation.attributes.configurations.forEach(configurationType => {
|
||||
injectables.add(configurationType);
|
||||
});
|
||||
|
||||
return Array.from(injectables);
|
||||
}
|
||||
|
||||
private findRunner(): Method | undefined {
|
||||
let clazz: Class = Class.forClassType(this._primaryClass);
|
||||
let methods = clazz.getOwnMethods();
|
||||
let methods = this._appClass.getOwnMethods();
|
||||
|
||||
for (let key of Array.from(methods.keys())) {
|
||||
let method = methods.get(key);
|
||||
|
@ -64,59 +88,58 @@ export class Application {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
private createContext(): ApplicationContext {
|
||||
let clazz: Class = Class.forClassType(this._primaryClass);
|
||||
// private createContext(): ApplicationContext {
|
||||
// let clazz: Class = Class.forClassType(this._primaryClass);
|
||||
|
||||
let ans = TypeUtil.ancestorsOf(this._primaryClass);
|
||||
|
||||
let wa: WebApplicationAnnotation = clazz.getOwnAnnotation(WebApplicationAnnotation);
|
||||
if (undefined === wa) {
|
||||
throw new Error(`Class is not WebApplication type. add @WebApplication annotation to class[${this._primaryClass.name}]`);
|
||||
}
|
||||
this._applicationContext = new ApplicationContext(wa.attributes.injectables);
|
||||
// let wa: WebApplicationAnnotation = clazz.getOwnAnnotation(WebApplicationAnnotation);
|
||||
// if (undefined === wa) {
|
||||
// throw new Error(`Class is not WebApplication type. add @WebApplication annotation to class[${this._primaryClass.name}]`);
|
||||
// }
|
||||
// this._applicationContext = new ApplicationContext(wa.attributes.injectables);
|
||||
|
||||
this.registerJSONSources(wa.attributes.jsonSources);
|
||||
this.registerConfigurations(wa.attributes.configurations);
|
||||
// this.registerJSONSources(wa.attributes.jsonSources);
|
||||
// this.registerConfigurations(wa.attributes.configurations);
|
||||
|
||||
return this._applicationContext;
|
||||
}
|
||||
// return this._applicationContext;
|
||||
// }
|
||||
|
||||
private registerJSONSources(jsonSources: any[]): void {
|
||||
if (undefined === jsonSources || null === jsonSources) {
|
||||
return;
|
||||
}
|
||||
let instanceFactory = this._applicationContext.instanceFactory;
|
||||
let jsons = Object.assign({}, ...jsonSources);
|
||||
instanceFactory.registerJSON(jsons);
|
||||
}
|
||||
// private registerJSONSources(jsonSources: any[]): void {
|
||||
// if (undefined === jsonSources || null === jsonSources) {
|
||||
// return;
|
||||
// }
|
||||
// let instanceFactory = this._applicationContext.instanceFactory;
|
||||
// let jsons = Object.assign({}, ...jsonSources);
|
||||
// instanceFactory.registerJSON(jsons);
|
||||
// }
|
||||
|
||||
private registerConfigurations(configurationTypes: ClassType[]): void {
|
||||
if (undefined === configurationTypes || null === configurationTypes) {
|
||||
return;
|
||||
}
|
||||
let instanceFactory = this._applicationContext.instanceFactory;
|
||||
// private registerConfigurations(configurationTypes: ClassType[]): void {
|
||||
// if (undefined === configurationTypes || null === configurationTypes) {
|
||||
// return;
|
||||
// }
|
||||
// let instanceFactory = this._applicationContext.instanceFactory;
|
||||
|
||||
configurationTypes.forEach(configurationType => {
|
||||
let clazz: Class = Class.forClassType(configurationType);
|
||||
let configAnnotation: ConfigurationAnnotation = clazz.getOwnAnnotation(ConfigurationAnnotation);
|
||||
if (undefined === configAnnotation) {
|
||||
throw new Error(`Class is not Configuration type. add @Configuration annotation to class[${configurationType.name}]`);
|
||||
}
|
||||
let methods = clazz.getOwnMethods();
|
||||
if (null === methods) {
|
||||
return;
|
||||
}
|
||||
let instance = clazz.getConstructor().newInstance();
|
||||
instanceFactory.applyInstance(configurationType, instance);
|
||||
methods.forEach(method => {
|
||||
let instanceAnnotation = method.getOwnAnnotation(InstanceAnnotation);
|
||||
if (undefined === instanceAnnotation) {
|
||||
return;
|
||||
}
|
||||
let singletonName = null === instanceAnnotation.attributes.name ? method.getName() : instanceAnnotation.attributes.name;
|
||||
let result = method.invoke(instance);
|
||||
instanceFactory.registerSingleton(singletonName, method.getReturnType(), result);
|
||||
});
|
||||
});
|
||||
}
|
||||
// configurationTypes.forEach(configurationType => {
|
||||
// let clazz: Class = Class.forClassType(configurationType);
|
||||
// let configAnnotation: ConfigurationAnnotation = clazz.getOwnAnnotation(ConfigurationAnnotation);
|
||||
// if (undefined === configAnnotation) {
|
||||
// throw new Error(`Class is not Configuration type. add @Configuration annotation to class[${configurationType.name}]`);
|
||||
// }
|
||||
// let methods = clazz.getOwnMethods();
|
||||
// if (null === methods) {
|
||||
// return;
|
||||
// }
|
||||
// let instance = clazz.getConstructor().newInstance();
|
||||
// instanceFactory.applyInstance(configurationType, instance);
|
||||
// methods.forEach(method => {
|
||||
// let instanceAnnotation = method.getOwnAnnotation(InstanceAnnotation);
|
||||
// if (undefined === instanceAnnotation) {
|
||||
// return;
|
||||
// }
|
||||
// let singletonName = null === instanceAnnotation.attributes.name ? method.getName() : instanceAnnotation.attributes.name;
|
||||
// let result = method.invoke(instance);
|
||||
// instanceFactory.registerSingleton(singletonName, method.getReturnType(), result);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
import {
|
||||
ClassType,
|
||||
} from '@overflow/commons/core/type';
|
||||
|
||||
import {
|
||||
Class,
|
||||
} from '@overflow/commons/core/reflect';
|
||||
|
||||
import {
|
||||
InstanceDefinition,
|
||||
InstanceFactory,
|
||||
} from '@overflow/commons/di/factory';
|
||||
|
||||
import { InstanceDefinitionReader } from './instance_definition_reader';
|
||||
|
||||
export class ApplicationContext {
|
||||
private _instanceFactory: InstanceFactory;
|
||||
private _instanceDefinitionReader: InstanceDefinitionReader;
|
||||
|
||||
public constructor(injectables: ClassType[]) {
|
||||
this._instanceFactory = new InstanceFactory();
|
||||
this._instanceDefinitionReader = new InstanceDefinitionReader();
|
||||
|
||||
this.initializeInjectables(injectables);
|
||||
}
|
||||
|
||||
private initializeInjectables(injectables: ClassType[]): void {
|
||||
if (undefined === injectables) {
|
||||
return;
|
||||
}
|
||||
injectables.forEach(injectable => {
|
||||
let name = injectable.name;
|
||||
let definition: InstanceDefinition = new InstanceDefinition(injectable);
|
||||
this._instanceFactory.registerInstanceDefinition(name, definition);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* instanceFactory
|
||||
*/
|
||||
public get instanceFactory(): InstanceFactory {
|
||||
return this._instanceFactory;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
import {
|
||||
ClassType,
|
||||
} from '@overflow/commons/core/type';
|
||||
|
||||
import {
|
||||
InstanceFactory,
|
||||
} from '@overflow/commons/di/factory';
|
||||
|
@ -10,66 +14,52 @@ import { InstanceDefinitionReader } from './instance_definition_reader';
|
|||
export class ApplicationContext {
|
||||
public static readonly MESSAGE_SOURCE_INSTANCE_NAME: string = 'messageSource';
|
||||
|
||||
private readonly instanceFactoryPostProcessors: InstanceFactoryPostProcessor[] = [];
|
||||
|
||||
private id: ApplicationContextIDType;
|
||||
private parent: ApplicationContext;
|
||||
private messageSource: MessageSource;
|
||||
private instanceFactory: InstanceFactory;
|
||||
private instanceDefinitionReader: InstanceDefinitionReader;
|
||||
private _id: ApplicationContextIDType;
|
||||
private _parent: ApplicationContext;
|
||||
private _messageSource: MessageSource;
|
||||
private _instanceFactory: InstanceFactory;
|
||||
private _instanceDefinitionReader: InstanceDefinitionReader;
|
||||
|
||||
public constructor(parent?: ApplicationContext) {
|
||||
this.setParent(parent);
|
||||
this.parent = parent;
|
||||
this._instanceFactory = new InstanceFactory();
|
||||
this._instanceDefinitionReader = new InstanceDefinitionReader(this._instanceFactory.instanceDefinitionRegistry);
|
||||
}
|
||||
|
||||
|
||||
// Context
|
||||
|
||||
public getID(): ApplicationContextIDType {
|
||||
public get id(): ApplicationContextIDType {
|
||||
return this.id;
|
||||
}
|
||||
public setID(id: ApplicationContextIDType): void {
|
||||
public set id(id: ApplicationContextIDType) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public getApplicationName(): string {
|
||||
public get applicationName(): string {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getParent(): ApplicationContext {
|
||||
return this.parent;
|
||||
public get parent(): ApplicationContext {
|
||||
return this._parent;
|
||||
}
|
||||
public setParent(parent: ApplicationContext): void {
|
||||
this.parent = parent;
|
||||
public set parent(parent: ApplicationContext) {
|
||||
this._parent = parent;
|
||||
}
|
||||
|
||||
public getInstanceFactory(): InstanceFactory {
|
||||
return undefined;
|
||||
public get instanceFactory(): InstanceFactory {
|
||||
return this._instanceFactory;
|
||||
}
|
||||
|
||||
public get instanceDefinitionReader(): InstanceDefinitionReader {
|
||||
return this._instanceDefinitionReader;
|
||||
}
|
||||
|
||||
// Configuration
|
||||
|
||||
public addInstanceFactoryPostProcessor(instanceFactoryPostProcessor: InstanceFactoryPostProcessor): void {
|
||||
this.instanceFactoryPostProcessors.push(instanceFactoryPostProcessor);
|
||||
}
|
||||
public getInstanceFactoryPostProcessor(): InstanceFactoryPostProcessor[] {
|
||||
return this.instanceFactoryPostProcessors;
|
||||
}
|
||||
|
||||
public addApplicationListener(listener: ApplicationListener): void {
|
||||
//
|
||||
}
|
||||
|
||||
public registerShutdownHook(): void {
|
||||
//
|
||||
}
|
||||
|
||||
public initMessageSource(): void {
|
||||
//
|
||||
}
|
||||
|
||||
// MessageSource
|
||||
public getMessageSource(): MessageSource {
|
||||
return this.messageSource;
|
||||
public get messageSource(): MessageSource {
|
||||
return this._messageSource;
|
||||
}
|
||||
|
||||
// Lifecycle
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
export * from './application_context';
|
||||
export * from './instance_definition_reader';
|
||||
export * from './scope_metadata';
|
||||
export * from './scope_metadata_resolver';
|
||||
|
|
|
@ -2,30 +2,63 @@ import {
|
|||
ClassType,
|
||||
} from '@overflow/commons/core/type';
|
||||
|
||||
import { Assert } from '@overflow/commons/core/util';
|
||||
import { Annotation } from '@overflow/commons/core/reflect';
|
||||
|
||||
import {
|
||||
Assert,
|
||||
AnnotationUtils,
|
||||
} from '@overflow/commons/core/util';
|
||||
|
||||
import {
|
||||
InstanceDefinitionRegistry, InstanceNameGenerator,
|
||||
InstanceDefinition,
|
||||
InstanceDefinitionRegistry,
|
||||
InstanceNameGenerator,
|
||||
} from '@overflow/commons/di/factory';
|
||||
|
||||
import {
|
||||
InstanceNameType,
|
||||
NotInjectableError,
|
||||
} from '@overflow/commons/di/type';
|
||||
|
||||
import { ScopeMetadataResolver } from './scope_metadata_resolver';
|
||||
import { InjectableAnnotation, QualifierAnnotation } from '@overflow/commons/di/decorators';
|
||||
|
||||
|
||||
export class InstanceDefinitionReader {
|
||||
private instanceDefinitionRegistry: InstanceDefinitionRegistry;
|
||||
private instanceNameGenerator: InstanceNameGenerator;
|
||||
private instanceNameGenerator: InstanceNameGenerator = new InstanceNameGenerator();
|
||||
private scopeMetadataResolver: ScopeMetadataResolver = new ScopeMetadataResolver();
|
||||
|
||||
public constructor(registry: InstanceDefinitionRegistry) {
|
||||
Assert.notNull(registry, 'InstanceDefinitionRegistry must not be null');
|
||||
this.instanceDefinitionRegistry = registry;
|
||||
}
|
||||
|
||||
public register(...injectables: ClassType[]): void {
|
||||
public registerInjectables(...injectables: ClassType[]): void {
|
||||
injectables.forEach(injectable => {
|
||||
this.registerInstance(injectable);
|
||||
this.registerInjectable(injectable, undefined);
|
||||
});
|
||||
}
|
||||
|
||||
public registerInstance(injectable: ClassType): void {
|
||||
let instanceDefinition: InstanceDefinition = new InstanceDefinition(injectable);
|
||||
public registerInjectable(injectable: ClassType, name: InstanceNameType | undefined, ...qualifiers: QualifierAnnotation[]): void {
|
||||
if (!AnnotationUtils.hasAnnotation(injectable, InjectableAnnotation)) {
|
||||
throw new NotInjectableError();
|
||||
}
|
||||
|
||||
let definition: InstanceDefinition = new InstanceDefinition(injectable);
|
||||
let scopeMeta = this.scopeMetadataResolver.resolveScopeMetadata(definition);
|
||||
definition.scope = scopeMeta.scope;
|
||||
let instanceName =
|
||||
undefined !== name
|
||||
? name
|
||||
: this.instanceNameGenerator.generateInstanceName(definition, this.instanceDefinitionRegistry);
|
||||
|
||||
if (undefined !== qualifiers) {
|
||||
qualifiers.forEach(qualifier => {
|
||||
definition.addQualifier(qualifier);
|
||||
});
|
||||
}
|
||||
|
||||
this.instanceDefinitionRegistry.registerInstanceDefinition(instanceName, definition);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { ScopeType } from '@overflow/commons/di/type';
|
||||
|
||||
export class ScopeMetadata {
|
||||
private _scope: ScopeType = ScopeType.Singleton;
|
||||
|
||||
public get scope(): ScopeType {
|
||||
return this._scope;
|
||||
}
|
||||
public set scope(scope: ScopeType) {
|
||||
this._scope = scope;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,12 +9,14 @@ import {
|
|||
import { ScopeAnnotation } from '@overflow/commons/di/decorators';
|
||||
import { InstanceDefinition } from '@overflow/commons/di/factory';
|
||||
import { ScopeType } from '@overflow/commons/di/type';
|
||||
import { ScopeMetadata } from './scope_metadata';
|
||||
|
||||
|
||||
export class ScopeMetadataResolver {
|
||||
protected static scopeAnnotationType: ClassType<Annotation> = ScopeAnnotation;
|
||||
|
||||
public resolveScopeMetadata(definition: InstanceDefinition): ScopeType {
|
||||
public resolveScopeMetadata(definition: InstanceDefinition): ScopeMetadata {
|
||||
let scopeMetadata: ScopeMetadata = new ScopeMetadata();
|
||||
let scope: ScopeType = ScopeType.Default;
|
||||
|
||||
}
|
||||
|
|
|
@ -14,13 +14,15 @@ import {
|
|||
|
||||
export interface InstanceAnnotationAttributes {
|
||||
name?: InstanceNameType;
|
||||
initMethod?: Function;
|
||||
destroyMethod?: Function;
|
||||
}
|
||||
|
||||
export class InstanceAnnotation extends Annotation {
|
||||
public readonly attributes: InstanceAnnotationAttributes = {
|
||||
};
|
||||
|
||||
public constructor(name: InstanceNameType | InstanceNameType[] | InstanceAnnotationAttributes) {
|
||||
public constructor(name: InstanceNameType | InstanceAnnotationAttributes) {
|
||||
super();
|
||||
if (undefined === name) {
|
||||
return;
|
||||
|
|
|
@ -8,12 +8,15 @@ import {
|
|||
PropertyKeyType,
|
||||
} from '@overflow/commons/core/type';
|
||||
|
||||
import { Configuration } from './configuration';
|
||||
|
||||
export interface WebApplicationAnnotationAttributes {
|
||||
jsonSources?: any[];
|
||||
injectables?: ClassType[];
|
||||
configurations?: ClassType[];
|
||||
}
|
||||
|
||||
@Configuration()
|
||||
export class WebApplicationAnnotation extends Annotation {
|
||||
public readonly attributes: WebApplicationAnnotationAttributes = {
|
||||
};
|
||||
|
|
36
src/ts/@overflow/commons/core/util/annotation.ts
Normal file
36
src/ts/@overflow/commons/core/util/annotation.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { Class, Annotation } from '@overflow/commons/core/reflect';
|
||||
import { ClassType } from '@overflow/commons/core/type';
|
||||
|
||||
export abstract class AnnotationUtils {
|
||||
public static hasAnnotation<T extends Annotation>(classType: ClassType, annotationClass: ClassType<T>): boolean {
|
||||
let annotation = AnnotationUtils.getAnnotation(classType, annotationClass);
|
||||
if (undefined !== annotation) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static getAnnotation<T extends Annotation>(classType: ClassType, annotationClass: ClassType<T>): T | undefined {
|
||||
let clazz = Class.forClassType(classType);
|
||||
if (undefined === clazz) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let annotations = clazz.getAnnotations();
|
||||
if (0 === annotations.size) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (const annonClassType of Array.from(annotations.keys())) {
|
||||
if (annonClassType === annotationClass) {
|
||||
return <T>annotations.get(annonClassType);
|
||||
}
|
||||
let annotation = AnnotationUtils.getAnnotation(annonClassType, annotationClass);
|
||||
if (undefined !== annotation) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { IllegalArgumentError } from '../type/error';
|
||||
import { StringUtil, StringUtils } from './string';
|
||||
import { StringUtils } from './string';
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from './annotation';
|
||||
export * from './assert';
|
||||
export * from './locale';
|
||||
export * from './registry';
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
export * from './inject';
|
||||
export * from './injectable';
|
||||
export * from './named';
|
||||
export * from './post_construct';
|
||||
export * from './pre_destroy';
|
||||
export * from './qualifier';
|
||||
|
|
|
@ -13,25 +13,25 @@ import {
|
|||
} from '@overflow/commons/di/type';
|
||||
|
||||
export interface InjectAnnotationAttributes {
|
||||
name?: InstanceNameType;
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export class InjectAnnotation extends Annotation {
|
||||
public readonly attributes: InjectAnnotationAttributes = {
|
||||
|
||||
required: true,
|
||||
};
|
||||
|
||||
public constructor(name: InstanceNameType | InjectAnnotationAttributes) {
|
||||
public constructor(required?: boolean | InjectAnnotationAttributes) {
|
||||
super();
|
||||
|
||||
if (undefined === name) {
|
||||
if (undefined === required) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.isString(name)) {
|
||||
this.attributes.name = <InstanceNameType>name;
|
||||
if (TypeUtil.isBoolean(required)) {
|
||||
this.attributes.required = <boolean>required;
|
||||
} else {
|
||||
this.copyAttributes(this.attributes, <InjectAnnotationAttributes>name);
|
||||
this.copyAttributes(this.attributes, <InjectAnnotationAttributes>required);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,24 +13,22 @@ import {
|
|||
} from '@overflow/commons/di/type';
|
||||
|
||||
export interface InjectableAnnotationAttributes {
|
||||
name?: InstanceNameType[];
|
||||
name?: InstanceNameType;
|
||||
}
|
||||
|
||||
export class InjectableAnnotation extends Annotation {
|
||||
public readonly attributes: InjectableAnnotationAttributes = {
|
||||
|
||||
name: undefined,
|
||||
};
|
||||
|
||||
public constructor(name: InstanceNameType | InstanceNameType[] | InjectableAnnotationAttributes) {
|
||||
public constructor(name?: InstanceNameType | InjectableAnnotationAttributes) {
|
||||
super();
|
||||
if (undefined === name) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.isString(name)) {
|
||||
this.attributes.name = [<InstanceNameType>name];
|
||||
} else if (TypeUtil.isArray(name)) {
|
||||
this.attributes.name = <InstanceNameType[]>name;
|
||||
this.attributes.name = <InstanceNameType>name;
|
||||
} else {
|
||||
this.copyAttributes(this.attributes, <InjectableAnnotationAttributes>name);
|
||||
}
|
||||
|
@ -40,11 +38,6 @@ export class InjectableAnnotation extends Annotation {
|
|||
console.log('Injectable');
|
||||
}
|
||||
|
||||
public methodDecorator<T>(target: Object, propertyKey: PropertyKeyType,
|
||||
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void {
|
||||
console.log('Injectable');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const Injectable = Decorator.create(InjectableAnnotation);
|
||||
|
|
|
@ -9,25 +9,14 @@ import {
|
|||
} from '@overflow/commons/core/type';
|
||||
|
||||
export interface PostConstructAnnotationAttributes {
|
||||
name?: string[];
|
||||
}
|
||||
|
||||
export class PostConstructAnnotation extends Annotation {
|
||||
public readonly attributes: PostConstructAnnotationAttributes = {
|
||||
|
||||
};
|
||||
|
||||
public constructor(name: string | string[] | PostConstructAnnotationAttributes) {
|
||||
public constructor() {
|
||||
super();
|
||||
if (undefined === name) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.isString(name)) {
|
||||
this.attributes.name = [<string>name];
|
||||
} else {
|
||||
this.copyAttributes(this.attributes, <PostConstructAnnotationAttributes>name);
|
||||
}
|
||||
}
|
||||
|
||||
public methodDecorator<T>(target: Object, propertyKey: PropertyKeyType,
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
} from '@overflow/commons/core/type';
|
||||
|
||||
export interface PreDestroyAnnotationAttributes {
|
||||
name?: string[];
|
||||
}
|
||||
|
||||
export class PreDestroyAnnotation extends Annotation {
|
||||
|
@ -17,17 +16,8 @@ export class PreDestroyAnnotation extends Annotation {
|
|||
|
||||
};
|
||||
|
||||
public constructor(name: string | string[] | PreDestroyAnnotationAttributes) {
|
||||
public constructor() {
|
||||
super();
|
||||
if (undefined === name) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.isString(name)) {
|
||||
this.attributes.name = [<string>name];
|
||||
} else {
|
||||
this.copyAttributes(this.attributes, <PreDestroyAnnotationAttributes>name);
|
||||
}
|
||||
}
|
||||
|
||||
public methodDecorator<T>(target: Object, propertyKey: PropertyKeyType,
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import {
|
||||
Annotation,
|
||||
Decorator,
|
||||
} from '@overflow/commons/core/reflect';
|
||||
|
||||
import {
|
||||
PropertyKeyType,
|
||||
TypeUtil,
|
||||
} from '@overflow/commons/core/type';
|
||||
|
||||
import {
|
||||
InstanceNameType,
|
||||
} from '@overflow/commons/di/type';
|
||||
|
||||
export interface QualifierAnnotationAttributes {
|
||||
name?: InstanceNameType;
|
||||
}
|
||||
|
||||
export class QualifierAnnotation extends Annotation {
|
||||
public readonly attributes: QualifierAnnotationAttributes = {
|
||||
name: '',
|
||||
};
|
||||
|
||||
public constructor(name: InstanceNameType | QualifierAnnotationAttributes) {
|
||||
super();
|
||||
if (undefined === name) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (TypeUtil.isString(name)) {
|
||||
this.attributes.name = <InstanceNameType>name;
|
||||
} else {
|
||||
this.copyAttributes(this.attributes, <QualifierAnnotationAttributes>name);
|
||||
}
|
||||
}
|
||||
|
||||
public classDecorator<TFunction extends Function>(target: TFunction): TFunction | void {
|
||||
console.log('Qualifier');
|
||||
}
|
||||
|
||||
public propertyDecorator(target: Object, propertyKey: PropertyKeyType): void {
|
||||
console.log('Qualifier');
|
||||
}
|
||||
|
||||
public methodDecorator<T>(target: Object, propertyKey: PropertyKeyType,
|
||||
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void {
|
||||
console.log('Qualifier');
|
||||
}
|
||||
|
||||
public parameterDecorator(target: Object, propertyKey: PropertyKeyType, parameterIndex: number): void {
|
||||
console.log('Qualifier');
|
||||
}
|
||||
}
|
||||
|
||||
export const Qualifier = Decorator.create(QualifierAnnotation);
|
|
@ -46,10 +46,6 @@ export class ResourceAnnotation extends Annotation {
|
|||
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void {
|
||||
console.log('Resource');
|
||||
}
|
||||
|
||||
public parameterDecorator(target: Object, propertyKey: PropertyKeyType, parameterIndex: number): void {
|
||||
console.log('Resource');
|
||||
}
|
||||
}
|
||||
|
||||
export const Resource = Decorator.create(ResourceAnnotation);
|
||||
|
|
|
@ -14,21 +14,21 @@ import {
|
|||
} from '@overflow/commons/di/type';
|
||||
|
||||
export interface ScopeAnnotationAttributes {
|
||||
value?: ScopeType;
|
||||
scope?: ScopeType;
|
||||
}
|
||||
|
||||
export class ScopeAnnotation extends Annotation {
|
||||
public readonly attributes: ScopeAnnotationAttributes = {
|
||||
value: ScopeType.Default,
|
||||
scope: ScopeType.Default,
|
||||
};
|
||||
|
||||
public constructor(value: ScopeType | ScopeAnnotationAttributes) {
|
||||
public constructor(scope: ScopeType | ScopeAnnotationAttributes) {
|
||||
super();
|
||||
|
||||
if (undefined !== (<ScopeAnnotationAttributes>value).value) {
|
||||
this.copyAttributes(this.attributes, <ScopeAnnotationAttributes>value);
|
||||
if (undefined !== (<ScopeAnnotationAttributes>scope).scope) {
|
||||
this.copyAttributes(this.attributes, <ScopeAnnotationAttributes>scope);
|
||||
} else {
|
||||
this.attributes.value = value;
|
||||
this.attributes.scope = <ScopeType>scope;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@ export class ValueAnnotation extends Annotation {
|
|||
console.log('Value');
|
||||
}
|
||||
|
||||
public methodDecorator<T>(target: Object, propertyKey: PropertyKeyType,
|
||||
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void {
|
||||
console.log('Value');
|
||||
}
|
||||
|
||||
public parameterDecorator(target: Object, propertyKey: PropertyKeyType, parameterIndex: number): void {
|
||||
console.log('Value');
|
||||
}
|
||||
|
|
|
@ -2,3 +2,4 @@ export * from './instance_definition_registry';
|
|||
export * from './instance_definition';
|
||||
export * from './instance_factory';
|
||||
export * from './instance_name_generator';
|
||||
export * from './singleton_instance_registry';
|
||||
|
|
|
@ -1,39 +1,41 @@
|
|||
import {
|
||||
Class,
|
||||
} from '@overflow/commons/core/reflect';
|
||||
|
||||
import {
|
||||
ClassType,
|
||||
} from '@overflow/commons/core/type';
|
||||
|
||||
import { Assert } from '@overflow/commons/core/util';
|
||||
import { ScopeType, InjectModeType } from '@overflow/commons/di/type';
|
||||
|
||||
import {
|
||||
QualifierAnnotation,
|
||||
} from '@overflow/commons/di/decorators';
|
||||
|
||||
import {
|
||||
ScopeType,
|
||||
InjectModeType,
|
||||
NotInjectableError,
|
||||
} from '@overflow/commons/di/type';
|
||||
|
||||
export class InstanceDefinition {
|
||||
private readonly attributes: Map<string, any> = new Map();
|
||||
private scope: ScopeType = ScopeType.Default;
|
||||
private injectMode: InjectModeType = InjectModeType.No;
|
||||
private _instanceClass: Class;
|
||||
private _scope: ScopeType = ScopeType.Default;
|
||||
private _injectMode: InjectModeType = InjectModeType.No;
|
||||
|
||||
// Attributes
|
||||
|
||||
public setAttribute(name: string, value?: any): void {
|
||||
Assert.notNull(name, 'Name must not be null');
|
||||
if (value !== undefined) {
|
||||
this.attributes.set(name, value);
|
||||
} else {
|
||||
this.removeAttribute(name);
|
||||
}
|
||||
public constructor(instanceClassType: ClassType) {
|
||||
let clazz = Class.forClassType(instanceClassType);
|
||||
if (undefined === clazz) {
|
||||
throw new NotInjectableError();
|
||||
}
|
||||
|
||||
public getAttribute(name: string): any | undefined {
|
||||
Assert.notNull(name, 'Name must not be null');
|
||||
return this.attributes.get(name);
|
||||
this._instanceClass = clazz;
|
||||
}
|
||||
|
||||
public removeAttribute(name: string): boolean {
|
||||
Assert.notNull(name, 'Name must not be null');
|
||||
return this.attributes.delete(name);
|
||||
}
|
||||
|
||||
public hasAttribute(name: string): boolean {
|
||||
Assert.notNull(name, 'Name must not be null');
|
||||
return this.attributes.has(name);
|
||||
}
|
||||
|
||||
public attributeNames(): IterableIterator<string> {
|
||||
return this.attributes.keys();
|
||||
public get instanceClass(): Class {
|
||||
return this._instanceClass;
|
||||
}
|
||||
|
||||
// Metadata
|
||||
|
@ -41,14 +43,22 @@ export class InstanceDefinition {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
public setScope(scope: ScopeType): void {
|
||||
public set scope(scope: ScopeType) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public getScope(): ScopeType {
|
||||
public get scope(): ScopeType {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
public get injectMode(): InjectModeType {
|
||||
return this._injectMode;
|
||||
}
|
||||
|
||||
public set injectMode(injectMode: InjectModeType) {
|
||||
this._injectMode = injectMode;
|
||||
}
|
||||
|
||||
public isSingleton(): boolean {
|
||||
return ScopeType.Singleton === this.scope || ScopeType.Default === this.scope;
|
||||
}
|
||||
|
@ -57,12 +67,7 @@ export class InstanceDefinition {
|
|||
return ScopeType.Transiant === this.scope;
|
||||
}
|
||||
|
||||
public setInjectMode(injectMode: InjectModeType): void {
|
||||
this.injectMode = injectMode;
|
||||
public addQualifier(qualifier: QualifierAnnotation): void {
|
||||
//
|
||||
}
|
||||
|
||||
public getInjectMode(): InjectModeType {
|
||||
return this.injectMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from '@overflow/commons/core/type';
|
||||
|
||||
import {
|
||||
InjectType,
|
||||
InjectModeType,
|
||||
InstanceNameType,
|
||||
} from '@overflow/commons/di/type';
|
||||
|
||||
|
@ -15,9 +15,13 @@ import { InstanceDefinition } from './instance_definition';
|
|||
import { InstanceDefinitionRegistry } from './instance_definition_registry';
|
||||
|
||||
export class InstanceFactory {
|
||||
private instanceDefinitionRegistry: InstanceDefinitionRegistry;
|
||||
private _instanceDefinitionRegistry: InstanceDefinitionRegistry;
|
||||
|
||||
|
||||
public get instanceDefinitionRegistry(): InstanceDefinitionRegistry {
|
||||
return this._instanceDefinitionRegistry;
|
||||
}
|
||||
|
||||
// Instance
|
||||
|
||||
public getInstance(name: InstanceNameType | undefined, requiredType: ClassType | undefined, ...args: any[]): any | undefined {
|
||||
|
@ -44,7 +48,7 @@ export class InstanceFactory {
|
|||
|
||||
// Create Instance
|
||||
|
||||
public createInstance<T>(clazzType: ClassType<T>, injectMode?: InjectType, dependencyCheck?: boolean): T {
|
||||
public createInstance<T>(clazzType: ClassType<T>, injectMode?: InjectModeType, dependencyCheck?: boolean): T {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
@ -52,11 +56,11 @@ export class InstanceFactory {
|
|||
//
|
||||
}
|
||||
|
||||
public inject(clazzType: ClassType, injectMode?: InjectType, dependencyCheck?: boolean): any {
|
||||
public inject(clazzType: ClassType, injectMode?: InjectModeType, dependencyCheck?: boolean): any {
|
||||
//
|
||||
}
|
||||
|
||||
public injectInstanceProperties(instance: any, injectMode: InjectType, dependencyCheck: boolean): void {
|
||||
public injectInstanceProperties(instance: any, injectMode: InjectModeType, dependencyCheck: boolean): void {
|
||||
//
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,13 @@ export class InstanceError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export class NotInjectableError extends InstanceError {
|
||||
public constructor(message?: string) {
|
||||
super(message);
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class NoSuchInstanceDefinitionError extends InstanceError {
|
||||
public constructor(message?: string) {
|
||||
super(message);
|
||||
|
|
Loading…
Reference in New Issue
Block a user