@deepkit/injector
Advanced tools
Comparing version 1.0.1-alpha.41 to 1.0.1-alpha.42
@@ -73,3 +73,4 @@ import { ClassSchema, ExtractClassDefinition, PlainSchemaProps, PropertySchema } from '@deepkit/type'; | ||
export interface BasicInjector { | ||
get<T, R = T extends ClassType<infer R> ? R : T>(token: T, frontInjector?: Injector): R; | ||
get<T, R = T extends ClassType<infer R> ? R : T>(token: T, frontInjector?: BasicInjector): R; | ||
getInjector(contextId: number): BasicInjector; | ||
} | ||
@@ -82,6 +83,12 @@ export declare class Injector implements BasicInjector { | ||
protected tagRegistry: TagRegistry; | ||
protected contextResolver?: { | ||
getInjector(contextId: number): BasicInjector; | ||
} | undefined; | ||
circularCheck: boolean; | ||
protected resolved: any[]; | ||
protected retriever(injector: Injector, token: any, frontInjector?: Injector): any; | ||
constructor(providers?: Provider[], parents?: (BasicInjector | Injector)[], injectorContext?: InjectorContext, configuredProviderRegistry?: ConfiguredProviderRegistry | undefined, tagRegistry?: TagRegistry); | ||
constructor(providers?: Provider[], parents?: (BasicInjector | Injector)[], injectorContext?: InjectorContext, configuredProviderRegistry?: ConfiguredProviderRegistry | undefined, tagRegistry?: TagRegistry, contextResolver?: { | ||
getInjector(contextId: number): BasicInjector; | ||
} | undefined); | ||
getInjector(contextId: number): BasicInjector; | ||
/** | ||
@@ -194,3 +201,2 @@ * Creates a clone of this instance, maintains the provider structure, but drops provider instances. | ||
protected cache: ScopedContextCache; | ||
static contextSymbol: symbol; | ||
constructor(contextManager?: ContextRegistry, scope?: string, configuredProviderRegistry?: ConfiguredProviderRegistry, parent?: InjectorContext | undefined, additionalInjectorParent?: Injector | undefined, modules?: { | ||
@@ -197,0 +203,0 @@ [name: string]: InjectorModule; |
@@ -169,3 +169,3 @@ "use strict"; | ||
class Injector { | ||
constructor(providers = [], parents = [], injectorContext = new InjectorContext, configuredProviderRegistry = undefined, tagRegistry = new provider_1.TagRegistry()) { | ||
constructor(providers = [], parents = [], injectorContext = new InjectorContext, configuredProviderRegistry = undefined, tagRegistry = new provider_1.TagRegistry(), contextResolver) { | ||
this.providers = providers; | ||
@@ -176,2 +176,3 @@ this.parents = parents; | ||
this.tagRegistry = tagRegistry; | ||
this.contextResolver = contextResolver; | ||
this.circularCheck = true; | ||
@@ -192,2 +193,5 @@ this.resolved = []; | ||
} | ||
getInjector(contextId) { | ||
return this.contextResolver ? this.contextResolver.getInjector(contextId) : this; | ||
} | ||
/** | ||
@@ -198,3 +202,3 @@ * Creates a clone of this instance, maintains the provider structure, but drops provider instances. | ||
fork(parents, injectorContext) { | ||
const injector = new Injector(undefined, parents || this.parents, injectorContext, this.configuredProviderRegistry, this.tagRegistry); | ||
const injector = new Injector(undefined, parents || this.parents, injectorContext, this.configuredProviderRegistry, this.tagRegistry, this.contextResolver); | ||
injector.providers = this.providers; | ||
@@ -264,3 +268,3 @@ injector.retriever = this.retriever; | ||
const providers = compiler.reserveVariable('tagRegistry', this.tagRegistry.resolve(token)); | ||
return `new ${tokenVar}(${providers}.map(v => frontInjector.retriever(frontInjector, v, frontInjector)))`; | ||
return `new ${tokenVar}(${providers}.map(v => (frontInjector.retriever ? frontInjector.retriever(frontInjector, v, frontInjector) : frontInjector.get(v, frontInjector))))`; | ||
} | ||
@@ -271,4 +275,4 @@ else { | ||
const tokenVar = compiler.reserveVariable('token', token); | ||
const orThrow = isOptional ? '' : `|| ${notFoundFunction}(${classTypeVar}, ${JSON.stringify(property.name)}, ${argPosition}, ${tokenVar})`; | ||
return `frontInjector.retriever(frontInjector, ${tokenVar}, frontInjector) ${orThrow}`; | ||
const orThrow = isOptional ? '' : `?? ${notFoundFunction}(${classTypeVar}, ${JSON.stringify(property.name)}, ${argPosition}, ${tokenVar})`; | ||
return `(frontInjector.retriever ? frontInjector.retriever(frontInjector, ${tokenVar}, frontInjector) : frontInjector.get(${tokenVar}, frontInjector)) ${orThrow}`; | ||
} | ||
@@ -278,2 +282,4 @@ return 'undefined'; | ||
createFactory(compiler, classType) { | ||
if (!classType) | ||
throw new Error('Can not create factory for undefined ClassType'); | ||
const schema = type_1.getClassSchema(classType); | ||
@@ -672,4 +678,3 @@ const args = []; | ||
get(token, frontInjector) { | ||
const context = typeof token === 'object' || typeof token === 'function' ? token[InjectorContext.contextSymbol] : undefined; | ||
const injector = this.getInjector(context ? context.id : 0); | ||
const injector = this.getInjector(0); | ||
return injector.get(token, frontInjector); | ||
@@ -682,3 +687,2 @@ } | ||
exports.InjectorContext = InjectorContext; | ||
InjectorContext.contextSymbol = Symbol('context'); | ||
//# sourceMappingURL=injector.js.map |
@@ -376,2 +376,35 @@ "use strict"; | ||
}); | ||
globals_1.test('constructor one with @inject', () => { | ||
class HttpKernel { | ||
} | ||
class Logger { | ||
} | ||
class Stopwatch { | ||
} | ||
let MyService = class MyService { | ||
constructor(httpKernel, logger, stopwatch) { | ||
this.httpKernel = httpKernel; | ||
this.logger = logger; | ||
this.stopwatch = stopwatch; | ||
} | ||
}; | ||
MyService = __decorate([ | ||
injector_1.injectable(), | ||
__param(2, injector_1.inject().optional), | ||
__metadata("design:paramtypes", [HttpKernel, | ||
Logger, | ||
Stopwatch]) | ||
], MyService); | ||
class SubService extends MyService { | ||
} | ||
{ | ||
const schema = type_1.getClassSchema(SubService); | ||
const methods = schema.getMethodProperties('constructor'); | ||
globals_1.expect(methods.length).toBe(3); | ||
globals_1.expect(methods[0].name).toBe('httpKernel'); | ||
globals_1.expect(methods[1].name).toBe('logger'); | ||
globals_1.expect(methods[2].name).toBe('stopwatch'); | ||
globals_1.expect(methods[2].data['deepkit/inject'].optional).toBe(true); | ||
} | ||
}); | ||
//# sourceMappingURL=injector.spec.js.map |
@@ -73,3 +73,4 @@ import { ClassSchema, ExtractClassDefinition, PlainSchemaProps, PropertySchema } from '@deepkit/type'; | ||
export interface BasicInjector { | ||
get<T, R = T extends ClassType<infer R> ? R : T>(token: T, frontInjector?: Injector): R; | ||
get<T, R = T extends ClassType<infer R> ? R : T>(token: T, frontInjector?: BasicInjector): R; | ||
getInjector(contextId: number): BasicInjector; | ||
} | ||
@@ -82,6 +83,12 @@ export declare class Injector implements BasicInjector { | ||
protected tagRegistry: TagRegistry; | ||
protected contextResolver?: { | ||
getInjector(contextId: number): BasicInjector; | ||
} | undefined; | ||
circularCheck: boolean; | ||
protected resolved: any[]; | ||
protected retriever(injector: Injector, token: any, frontInjector?: Injector): any; | ||
constructor(providers?: Provider[], parents?: (BasicInjector | Injector)[], injectorContext?: InjectorContext, configuredProviderRegistry?: ConfiguredProviderRegistry | undefined, tagRegistry?: TagRegistry); | ||
constructor(providers?: Provider[], parents?: (BasicInjector | Injector)[], injectorContext?: InjectorContext, configuredProviderRegistry?: ConfiguredProviderRegistry | undefined, tagRegistry?: TagRegistry, contextResolver?: { | ||
getInjector(contextId: number): BasicInjector; | ||
} | undefined); | ||
getInjector(contextId: number): BasicInjector; | ||
/** | ||
@@ -194,3 +201,2 @@ * Creates a clone of this instance, maintains the provider structure, but drops provider instances. | ||
protected cache: ScopedContextCache; | ||
static contextSymbol: symbol; | ||
constructor(contextManager?: ContextRegistry, scope?: string, configuredProviderRegistry?: ConfiguredProviderRegistry, parent?: InjectorContext | undefined, additionalInjectorParent?: Injector | undefined, modules?: { | ||
@@ -197,0 +203,0 @@ [name: string]: InjectorModule; |
@@ -153,3 +153,3 @@ /* | ||
export class Injector { | ||
constructor(providers = [], parents = [], injectorContext = new InjectorContext, configuredProviderRegistry = undefined, tagRegistry = new TagRegistry()) { | ||
constructor(providers = [], parents = [], injectorContext = new InjectorContext, configuredProviderRegistry = undefined, tagRegistry = new TagRegistry(), contextResolver) { | ||
this.providers = providers; | ||
@@ -160,2 +160,3 @@ this.parents = parents; | ||
this.tagRegistry = tagRegistry; | ||
this.contextResolver = contextResolver; | ||
this.circularCheck = true; | ||
@@ -176,2 +177,5 @@ this.resolved = []; | ||
} | ||
getInjector(contextId) { | ||
return this.contextResolver ? this.contextResolver.getInjector(contextId) : this; | ||
} | ||
/** | ||
@@ -182,3 +186,3 @@ * Creates a clone of this instance, maintains the provider structure, but drops provider instances. | ||
fork(parents, injectorContext) { | ||
const injector = new Injector(undefined, parents || this.parents, injectorContext, this.configuredProviderRegistry, this.tagRegistry); | ||
const injector = new Injector(undefined, parents || this.parents, injectorContext, this.configuredProviderRegistry, this.tagRegistry, this.contextResolver); | ||
injector.providers = this.providers; | ||
@@ -248,3 +252,3 @@ injector.retriever = this.retriever; | ||
const providers = compiler.reserveVariable('tagRegistry', this.tagRegistry.resolve(token)); | ||
return `new ${tokenVar}(${providers}.map(v => frontInjector.retriever(frontInjector, v, frontInjector)))`; | ||
return `new ${tokenVar}(${providers}.map(v => (frontInjector.retriever ? frontInjector.retriever(frontInjector, v, frontInjector) : frontInjector.get(v, frontInjector))))`; | ||
} | ||
@@ -255,4 +259,4 @@ else { | ||
const tokenVar = compiler.reserveVariable('token', token); | ||
const orThrow = isOptional ? '' : `|| ${notFoundFunction}(${classTypeVar}, ${JSON.stringify(property.name)}, ${argPosition}, ${tokenVar})`; | ||
return `frontInjector.retriever(frontInjector, ${tokenVar}, frontInjector) ${orThrow}`; | ||
const orThrow = isOptional ? '' : `?? ${notFoundFunction}(${classTypeVar}, ${JSON.stringify(property.name)}, ${argPosition}, ${tokenVar})`; | ||
return `(frontInjector.retriever ? frontInjector.retriever(frontInjector, ${tokenVar}, frontInjector) : frontInjector.get(${tokenVar}, frontInjector)) ${orThrow}`; | ||
} | ||
@@ -262,2 +266,4 @@ return 'undefined'; | ||
createFactory(compiler, classType) { | ||
if (!classType) | ||
throw new Error('Can not create factory for undefined ClassType'); | ||
const schema = getClassSchema(classType); | ||
@@ -648,4 +654,3 @@ const args = []; | ||
get(token, frontInjector) { | ||
const context = typeof token === 'object' || typeof token === 'function' ? token[InjectorContext.contextSymbol] : undefined; | ||
const injector = this.getInjector(context ? context.id : 0); | ||
const injector = this.getInjector(0); | ||
return injector.get(token, frontInjector); | ||
@@ -657,3 +662,2 @@ } | ||
} | ||
InjectorContext.contextSymbol = Symbol('context'); | ||
//# sourceMappingURL=injector.js.map |
@@ -14,3 +14,3 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
import { expect, test } from '@jest/globals'; | ||
import { t } from '@deepkit/type'; | ||
import { getClassSchema, t } from '@deepkit/type'; | ||
import 'reflect-metadata'; | ||
@@ -374,2 +374,35 @@ import { CircularDependencyError, createConfig, inject, injectable, Injector, InjectorContext } from '../src/injector'; | ||
}); | ||
test('constructor one with @inject', () => { | ||
class HttpKernel { | ||
} | ||
class Logger { | ||
} | ||
class Stopwatch { | ||
} | ||
let MyService = class MyService { | ||
constructor(httpKernel, logger, stopwatch) { | ||
this.httpKernel = httpKernel; | ||
this.logger = logger; | ||
this.stopwatch = stopwatch; | ||
} | ||
}; | ||
MyService = __decorate([ | ||
injectable(), | ||
__param(2, inject().optional), | ||
__metadata("design:paramtypes", [HttpKernel, | ||
Logger, | ||
Stopwatch]) | ||
], MyService); | ||
class SubService extends MyService { | ||
} | ||
{ | ||
const schema = getClassSchema(SubService); | ||
const methods = schema.getMethodProperties('constructor'); | ||
expect(methods.length).toBe(3); | ||
expect(methods[0].name).toBe('httpKernel'); | ||
expect(methods[1].name).toBe('logger'); | ||
expect(methods[2].name).toBe('stopwatch'); | ||
expect(methods[2].data['deepkit/inject'].optional).toBe(true); | ||
} | ||
}); | ||
//# sourceMappingURL=injector.spec.js.map |
{ | ||
"name": "@deepkit/injector", | ||
"version": "1.0.1-alpha.41", | ||
"version": "1.0.1-alpha.42", | ||
"description": "Deepkit Dependency Injection", | ||
@@ -30,4 +30,4 @@ "type": "commonjs", | ||
"devDependencies": { | ||
"@deepkit/core": "^1.0.1-alpha.39", | ||
"@deepkit/type": "^1.0.1-alpha.40", | ||
"@deepkit/core": "^1.0.1-alpha.42", | ||
"@deepkit/type": "^1.0.1-alpha.42", | ||
"reflect-metadata": "^0.1.13" | ||
@@ -43,3 +43,3 @@ }, | ||
}, | ||
"gitHead": "4766c5a7229111f59f19e47e4f20332e282679a6" | ||
"gitHead": "8973e01e1596c0b5dac4b61ff2325a89e82e1ec0" | ||
} |
@@ -210,3 +210,4 @@ /* | ||
export interface BasicInjector { | ||
get<T, R = T extends ClassType<infer R> ? R : T>(token: T, frontInjector?: Injector): R; | ||
get<T, R = T extends ClassType<infer R> ? R : T>(token: T, frontInjector?: BasicInjector): R; | ||
getInjector(contextId: number): BasicInjector; | ||
} | ||
@@ -232,3 +233,4 @@ | ||
protected configuredProviderRegistry: ConfiguredProviderRegistry | undefined = undefined, | ||
protected tagRegistry: TagRegistry = new TagRegistry() | ||
protected tagRegistry: TagRegistry = new TagRegistry(), | ||
protected contextResolver?: { getInjector(contextId: number): BasicInjector } | ||
) { | ||
@@ -239,2 +241,6 @@ if (!this.configuredProviderRegistry) this.configuredProviderRegistry = injectorContext.configuredProviderRegistry; | ||
getInjector(contextId: number): BasicInjector { | ||
return this.contextResolver ? this.contextResolver.getInjector(contextId) : this; | ||
} | ||
/** | ||
@@ -245,3 +251,3 @@ * Creates a clone of this instance, maintains the provider structure, but drops provider instances. | ||
public fork(parents?: Injector[], injectorContext?: InjectorContext) { | ||
const injector = new Injector(undefined, parents || this.parents, injectorContext, this.configuredProviderRegistry, this.tagRegistry); | ||
const injector = new Injector(undefined, parents || this.parents, injectorContext, this.configuredProviderRegistry, this.tagRegistry, this.contextResolver); | ||
injector.providers = this.providers; | ||
@@ -309,9 +315,9 @@ injector.retriever = this.retriever; | ||
const providers = compiler.reserveVariable('tagRegistry', this.tagRegistry.resolve(token)); | ||
return `new ${tokenVar}(${providers}.map(v => frontInjector.retriever(frontInjector, v, frontInjector)))`; | ||
return `new ${tokenVar}(${providers}.map(v => (frontInjector.retriever ? frontInjector.retriever(frontInjector, v, frontInjector) : frontInjector.get(v, frontInjector))))`; | ||
} else { | ||
if (token === undefined) throw new Error(`Argument type of '${property.name}' at position ${argPosition} is undefined. Imported reflect-metadata correctly? For circular references use @inject(() => T) ${property.name}:T.`); | ||
const tokenVar = compiler.reserveVariable('token', token); | ||
const orThrow = isOptional ? '' : `|| ${notFoundFunction}(${classTypeVar}, ${JSON.stringify(property.name)}, ${argPosition}, ${tokenVar})`; | ||
const orThrow = isOptional ? '' : `?? ${notFoundFunction}(${classTypeVar}, ${JSON.stringify(property.name)}, ${argPosition}, ${tokenVar})`; | ||
return `frontInjector.retriever(frontInjector, ${tokenVar}, frontInjector) ${orThrow}`; | ||
return `(frontInjector.retriever ? frontInjector.retriever(frontInjector, ${tokenVar}, frontInjector) : frontInjector.get(${tokenVar}, frontInjector)) ${orThrow}`; | ||
} | ||
@@ -323,2 +329,3 @@ | ||
protected createFactory(compiler: CompilerContext, classType: ClassType): string { | ||
if (!classType) throw new Error('Can not create factory for undefined ClassType'); | ||
const schema = getClassSchema(classType); | ||
@@ -681,4 +688,2 @@ const args: string[] = []; | ||
public static contextSymbol = Symbol('context'); | ||
constructor( | ||
@@ -762,4 +767,3 @@ public readonly contextManager: ContextRegistry = new ContextRegistry, | ||
public get<T, R = T extends ClassType<infer R> ? R : T>(token: T, frontInjector?: Injector): R { | ||
const context = typeof token === 'object' || typeof token === 'function' ? (token as any)[InjectorContext.contextSymbol] as Context : undefined; | ||
const injector = this.getInjector(context ? context.id : 0); | ||
const injector = this.getInjector(0); | ||
return injector.get(token, frontInjector); | ||
@@ -766,0 +770,0 @@ } |
import { expect, test } from '@jest/globals'; | ||
import { t } from '@deepkit/type'; | ||
import { getClassSchema, t } from '@deepkit/type'; | ||
import 'reflect-metadata'; | ||
import { CircularDependencyError, createConfig, inject, injectable, Injector, InjectorContext } from '../src/injector'; | ||
import { CircularDependencyError, createConfig, inject, injectable, InjectOptions, Injector, InjectorContext } from '../src/injector'; | ||
import { InjectorModule } from '../src/module'; | ||
@@ -362,1 +362,38 @@ | ||
}); | ||
test('constructor one with @inject', () => { | ||
class HttpKernel { | ||
} | ||
class Logger { | ||
} | ||
class Stopwatch { | ||
} | ||
@injectable() | ||
class MyService { | ||
constructor( | ||
protected httpKernel: HttpKernel, | ||
public logger: Logger, | ||
@inject().optional protected stopwatch?: Stopwatch, | ||
) { | ||
} | ||
} | ||
class SubService extends MyService { | ||
} | ||
{ | ||
const schema = getClassSchema(SubService); | ||
const methods = schema.getMethodProperties('constructor'); | ||
expect(methods.length).toBe(3); | ||
expect(methods[0].name).toBe('httpKernel'); | ||
expect(methods[1].name).toBe('logger'); | ||
expect(methods[2].name).toBe('stopwatch'); | ||
expect((methods[2].data['deepkit/inject'] as InjectOptions).optional).toBe(true); | ||
} | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
322578
4454