Comparing version 0.0.19 to 0.0.20
@@ -0,1 +1,2 @@ | ||
import { Injector } from './injector'; | ||
export interface ConstructAnnotation { | ||
@@ -9,5 +10,8 @@ arguments: any[]; | ||
} | ||
export interface PropertyDecoratorContextCallback { | ||
(instance: any, propertyName: string | Symbol, injector: Injector): void; | ||
} | ||
export interface PropertyAnnotation { | ||
propertyKey: string | Symbol; | ||
params: any[]; | ||
contextCallback: PropertyDecoratorContextCallback; | ||
} | ||
@@ -19,6 +23,6 @@ export interface MethodAnnotation { | ||
export declare class Annotations { | ||
private klass; | ||
private prop; | ||
private method; | ||
private param; | ||
private classes; | ||
private props; | ||
private methods; | ||
private params; | ||
pushClassMetadata(token: any, params: ConstructAnnotation): void; | ||
@@ -28,2 +32,3 @@ getClassMetadata(token: any): ConstructAnnotation; | ||
getParamMetadata(token: any): ParamAnnotation[]; | ||
getPropMetadataKeys(): any[]; | ||
pushPropMetadata(token: any, params: PropertyAnnotation): void; | ||
@@ -30,0 +35,0 @@ getPropMetadata(token: any): PropertyAnnotation[]; |
export class Annotations { | ||
constructor() { | ||
this.klass = new Map(); | ||
this.prop = new Map(); | ||
this.method = new Map(); | ||
this.param = new Map(); | ||
this.classes = new Map(); | ||
this.props = new Map(); | ||
this.methods = new Map(); | ||
this.params = new Map(); | ||
} | ||
pushClassMetadata(token, params) { | ||
this.klass.set(token, params); | ||
this.classes.set(token, params); | ||
} | ||
getClassMetadata(token) { | ||
return this.klass.get(token); | ||
return this.classes.get(token); | ||
} | ||
pushParamMetadata(token, params) { | ||
if (!this.param.has(token)) { | ||
this.param.set(token, [params]); | ||
if (!this.params.has(token)) { | ||
this.params.set(token, [params]); | ||
} | ||
else { | ||
this.param.get(token).push(params); | ||
this.params.get(token).push(params); | ||
} | ||
} | ||
getParamMetadata(token) { | ||
return this.param.get(token); | ||
return this.params.get(token); | ||
} | ||
getPropMetadataKeys() { | ||
return Array.from(this.props.keys()); | ||
} | ||
pushPropMetadata(token, params) { | ||
if (!this.prop.has(token)) { | ||
this.prop.set(token, [params]); | ||
if (!this.props.has(token)) { | ||
this.props.set(token, [params]); | ||
} | ||
else { | ||
this.prop.get(token).push(params); | ||
this.props.get(token).push(params); | ||
} | ||
} | ||
getPropMetadata(token) { | ||
return this.prop.get(token); | ||
return this.props.get(token); | ||
} | ||
pushMethodMetadata(token, params) { | ||
if (!this.method.has(token)) { | ||
this.method.set(token, [params]); | ||
if (!this.methods.has(token)) { | ||
this.methods.set(token, [params]); | ||
} | ||
else { | ||
this.method.get(token).push(params); | ||
this.methods.get(token).push(params); | ||
} | ||
} | ||
getMethodMetadata(token) { | ||
return this.method.get(token); | ||
return this.methods.get(token); | ||
} | ||
} |
@@ -1,6 +0,6 @@ | ||
import { Annotations } from './annotations'; | ||
import { Annotations, PropertyDecoratorContextCallback } from './annotations'; | ||
export declare function makeParamDecorator(token: any, ...params: any[]): ParameterDecorator; | ||
export declare function makePropertyDecorator(token: any, ...params: any[]): PropertyDecorator; | ||
export declare function makePropertyDecorator(token: any, contextCallback: PropertyDecoratorContextCallback): PropertyDecorator; | ||
export declare function makeMethodDecorator(token: any, ...params: any[]): MethodDecorator; | ||
export declare function makeClassDecorator(token: any, ...params: any[]): ClassDecorator; | ||
export declare function getAnnotations(target: any): Annotations; |
import { Annotations } from './annotations'; | ||
export function makeParamDecorator(token, ...params) { | ||
return function (target, propertyKey, parameterIndex) { | ||
const annotations = getAnnotations(target); | ||
const annotations = getAnnotations(target.constructor); | ||
annotations.pushParamMetadata(token, { | ||
@@ -11,8 +11,8 @@ parameterIndex, | ||
} | ||
export function makePropertyDecorator(token, ...params) { | ||
export function makePropertyDecorator(token, contextCallback) { | ||
return function (target, propertyKey) { | ||
const annotations = getAnnotations(target); | ||
const annotations = getAnnotations(target.constructor); | ||
annotations.pushPropMetadata(token, { | ||
propertyKey, | ||
params | ||
contextCallback | ||
}); | ||
@@ -23,3 +23,3 @@ }; | ||
return function (target, methodName) { | ||
const annotations = getAnnotations(target); | ||
const annotations = getAnnotations(target.constructor); | ||
annotations.pushMethodMetadata(token, { | ||
@@ -26,0 +26,0 @@ methodName, |
@@ -35,1 +35,9 @@ import { Type } from './type'; | ||
} | ||
export interface Prop { | ||
token: any; | ||
} | ||
export interface PropDecorator { | ||
(token: any): PropertyDecorator; | ||
new (token: any): Prop; | ||
} | ||
export declare const Prop: PropDecorator; |
@@ -1,2 +0,4 @@ | ||
import { makeParamDecorator } from './decorators'; | ||
import { makeParamDecorator, makePropertyDecorator } from './decorators'; | ||
import { ForwardRef } from './forward-ref'; | ||
import { THROW_IF_NOT_FOUND } from './null-injector'; | ||
export const Inject = function InjectDecorator(token) { | ||
@@ -25,1 +27,11 @@ if (this instanceof InjectDecorator) { | ||
}; | ||
export const Prop = function PropDecorator(token, notFoundValue = THROW_IF_NOT_FOUND, flags) { | ||
if (this instanceof PropDecorator) { | ||
this.token = token; | ||
} | ||
else { | ||
return makePropertyDecorator(Prop, function (instance, propertyName, injector) { | ||
instance[propertyName] = injector.get(token instanceof ForwardRef ? token.getRef() : token, notFoundValue, flags); | ||
}); | ||
} | ||
}; |
@@ -28,9 +28,9 @@ import { InjectFlags, Injector } from './injector'; | ||
for (let i = 0; i < this.normalizedProviders.length; i++) { | ||
const { provide, deps, factory } = this.normalizedProviders[i]; | ||
const { provide, deps, generateFactory } = this.normalizedProviders[i]; | ||
if (provide === token) { | ||
const ff = factory(this, (token, value) => { | ||
const factory = generateFactory(this, (token, value) => { | ||
this.reflectiveValues.set(token, value); | ||
}); | ||
const params = this.resolveDeps(deps || [], notFoundValue); | ||
let reflectiveValue = ff(...params); | ||
let reflectiveValue = factory(...params); | ||
this.reflectiveValues.set(token, reflectiveValue); | ||
@@ -37,0 +37,0 @@ return reflectiveValue; |
@@ -11,5 +11,5 @@ import { Provider } from './provider'; | ||
provide: any; | ||
factory: (injector: Injector, cacheFn: (token: any, value: any) => void) => (...args: any[]) => any; | ||
generateFactory: (injector: Injector, cacheFn: (token: any, value: any) => void) => (...args: any[]) => any; | ||
deps: ReflectiveDependency[]; | ||
} | ||
export declare function normalizeProviders(providers: Provider[]): NormalizedProvider[]; |
import { Inject, Optional, Self, SkipSelf } from './metadata'; | ||
import { Injectable } from './injectable'; | ||
import { stringify } from './utils/_api'; | ||
import { getAnnotations } from './decorators'; | ||
export function normalizeProviders(providers) { | ||
return providers.map(item => { | ||
if (item.useValue) { | ||
return normalizeValueProviderFactory(item); | ||
return providers.map(provider => { | ||
if (provider.useValue) { | ||
return normalizeValueProviderFactory(provider); | ||
} | ||
else if (item.useClass) { | ||
return normalizeClassProviderFactory(item); | ||
else if (provider.useClass) { | ||
return normalizeClassProviderFactory(provider); | ||
} | ||
else if (item.useExisting) { | ||
return normalizeExistingProviderFactory(item); | ||
else if (provider.useExisting) { | ||
return normalizeExistingProviderFactory(provider); | ||
} | ||
else if (item.useFactory) { | ||
return normalizeFactoryProviderFactory(item); | ||
else if (provider.useFactory) { | ||
return normalizeFactoryProviderFactory(provider); | ||
} | ||
else if (item.provide) { | ||
return normalizeConstructorProviderFactory(item); | ||
else if (provider.provide) { | ||
return normalizeConstructorProviderFactory(provider); | ||
} | ||
else { | ||
return normalizeTypeProviderFactory(item); | ||
return normalizeTypeProviderFactory(provider); | ||
} | ||
@@ -29,3 +30,3 @@ }); | ||
provide: provider.provide, | ||
factory() { | ||
generateFactory() { | ||
return function () { | ||
@@ -48,10 +49,17 @@ return provider.useValue; | ||
provide: provider.provide, | ||
factory(injector, cacheFn) { | ||
deps, | ||
generateFactory(injector, cacheFn) { | ||
return function (...args) { | ||
const instance = new provider.useClass(...args); | ||
const propMetadataKeys = getAnnotations(provider.useClass).getPropMetadataKeys(); | ||
propMetadataKeys.forEach(key => { | ||
const propsMetadata = getAnnotations(provider.useClass).getPropMetadata(key) || []; | ||
propsMetadata.forEach(item => { | ||
item.contextCallback(instance, item.propertyKey, injector); | ||
}); | ||
}); | ||
cacheFn(provider.useClass, instance); | ||
return instance; | ||
}; | ||
}, | ||
deps | ||
} | ||
}; | ||
@@ -62,3 +70,3 @@ } | ||
provide: provider.provide, | ||
factory(injector) { | ||
generateFactory(injector) { | ||
return function () { | ||
@@ -74,3 +82,3 @@ return injector.get(provider.useExisting); | ||
provide: provider.provide, | ||
factory() { | ||
generateFactory() { | ||
return function (...args) { | ||
@@ -93,3 +101,3 @@ return provider.useFactory(...args); | ||
function resolveClassParams(construct) { | ||
const annotations = construct.__annotations__; | ||
const annotations = getAnnotations(construct); | ||
if (typeof annotations === 'undefined' || typeof annotations.getClassMetadata(Injectable) === 'undefined') { | ||
@@ -96,0 +104,0 @@ throw new Error(`class/function \`${stringify(construct)}\` is not injectable!`); |
{ | ||
"name": "@tanbo/di", | ||
"version": "0.0.19", | ||
"version": "0.0.20", | ||
"description": "A dependency injection Library", | ||
@@ -5,0 +5,0 @@ "main": "./bundles/public-api.js", |
23229
640