@travetto/di
Advanced tools
Comparing version 2.0.0-alpha.6 to 2.0.0-alpha.7
{ | ||
"name": "@travetto/di", | ||
"displayName": "Dependency Injection", | ||
"version": "2.0.0-alpha.6", | ||
"version": "2.0.0-alpha.7", | ||
"description": "Dependency registration/management and injection support.", | ||
@@ -32,7 +32,7 @@ "keywords": [ | ||
"dependencies": { | ||
"@travetto/transformer": "^2.0.0-alpha.5", | ||
"@travetto/registry": "^2.0.0-alpha.6" | ||
"@travetto/transformer": "^2.0.0-alpha.6", | ||
"@travetto/registry": "^2.0.0-alpha.7" | ||
}, | ||
"devDependencies": { | ||
"@travetto/config": "^2.0.0-alpha.5" | ||
"@travetto/config": "^2.0.0-alpha.6" | ||
}, | ||
@@ -39,0 +39,0 @@ "docDependencies": { |
@@ -14,3 +14,3 @@ <!-- This file was generated by @travetto/doc and should not be modified directly --> | ||
## Declaration | ||
The [@Injectable](https://github.com/travetto/travetto/tree/master/module/di/src/decorator.ts#L30) and [@InjectableFactory](https://github.com/travetto/travetto/tree/master/module/di/src/decorator.ts#L72) decorators provide the registration of dependencies. Dependency declaration revolves around exposing `class`es and subtypes thereof to provide necessary functionality. Additionally, the framework will utilize dependencies to satisfy contracts with various implementations (e.g. [MongoModelService](https://github.com/travetto/travetto/tree/master/module/model-mongo/src/service.ts#L45) provides itself as an injectable candidate for [ModelCrudSupport](https://github.com/travetto/travetto/tree/master/module/model/src/service/crud.ts). | ||
The [@Injectable](https://github.com/travetto/travetto/tree/master/module/di/src/decorator.ts#L30) and [@InjectableFactory](https://github.com/travetto/travetto/tree/master/module/di/src/decorator.ts#L72) decorators provide the registration of dependencies. Dependency declaration revolves around exposing `class`es and subtypes thereof to provide necessary functionality. Additionally, the framework will utilize dependencies to satisfy contracts with various implementations (e.g. [MongoModelService](https://github.com/travetto/travetto/tree/master/module/model-mongo/src/service.ts#L46) provides itself as an injectable candidate for [ModelCrudSupport](https://github.com/travetto/travetto/tree/master/module/model/src/service/crud.ts). | ||
@@ -17,0 +17,0 @@ **Code: Example Injectable** |
@@ -5,3 +5,3 @@ import { Class, ClassInstance } from '@travetto/base'; | ||
import { InjectableFactoryConfig, InjectableConfig, Dependency } from './types'; | ||
import { DependencyRegistry } from './registry'; | ||
import { DependencyRegistry, ResolutionType } from './registry'; | ||
@@ -41,3 +41,3 @@ function collapseConfig<T extends { qualifier?: symbol }>(...args: (symbol | Partial<InjectConfig> | undefined)[]) { | ||
export type InjectConfig = { qualifier?: symbol, optional?: boolean, resolution?: 'loose' | 'strict' }; | ||
export type InjectConfig = { qualifier?: symbol, optional?: boolean, resolution?: ResolutionType }; | ||
@@ -44,0 +44,0 @@ export function InjectArgs(configs?: InjectConfig[][]) { |
import { Class, ClassInstance, ConcreteClass } from '@travetto/base'; | ||
import { MetadataRegistry, RootRegistry, ChangeEvent } from '@travetto/registry'; | ||
import { Watchable } from '@travetto/base/src/internal/watchable'; | ||
import { Dynamic } from '@travetto/base/src/internal/dynamic'; | ||
@@ -10,7 +10,8 @@ import { Dependency, InjectableConfig, ClassTarget, InjectableFactoryConfig } from './types'; | ||
type ClassId = string; | ||
type Resolution = 'strict' | 'loose'; | ||
type Resolved<T> = { config: InjectableConfig<T>, qualifier: symbol, id: string }; | ||
const PrimaryCandidateSym = Symbol.for('@trv:di/primary'); | ||
export type ResolutionType = 'strict' | 'loose' | 'any'; | ||
const PrimaryCandidateⲐ = Symbol.for('@trv:di/primary'); | ||
function hasPostConstruct(o: unknown): o is { postConstruct: () => Promise<unknown> } { | ||
@@ -28,3 +29,3 @@ return !!o && !!(o as Record<string, unknown>)['postConstruct']; | ||
*/ | ||
@Watchable('@travetto/di/support/watch.injection') | ||
@Dynamic('@travetto/di/support/dynamic.injection') | ||
class $DependencyRegistry extends MetadataRegistry<InjectableConfig> { | ||
@@ -52,3 +53,3 @@ protected pendingFinalize: Class[] = []; | ||
*/ | ||
protected resolveTarget<T>(target: ClassTarget<T>, qualifier?: symbol, resolution?: Resolution): Resolved<T> { | ||
protected resolveTarget<T>(target: ClassTarget<T>, qualifier?: symbol, resolution?: ResolutionType): Resolved<T> { | ||
const qualifiers = this.targetToClass.get(target.ᚕid) ?? new Map<symbol, string>(); | ||
@@ -64,4 +65,4 @@ | ||
// If primary found | ||
if (qualifiers.has(PrimaryCandidateSym)) { | ||
qualifier = PrimaryCandidateSym; | ||
if (qualifiers.has(PrimaryCandidateⲐ)) { | ||
qualifier = PrimaryCandidateⲐ; | ||
} else { | ||
@@ -78,3 +79,7 @@ // If there is only one default symbol | ||
} else { | ||
throw new InjectionError('Dependency has multiple candidates', target, filtered); | ||
if (resolution === 'any') { | ||
qualifier = filtered[0]; | ||
} else { | ||
throw new InjectionError('Dependency has multiple candidates', target, filtered); | ||
} | ||
} | ||
@@ -259,3 +264,3 @@ } | ||
*/ | ||
async getInstance<T>(target: ClassTarget<T>, qual?: symbol, resolution?: Resolution): Promise<T> { | ||
async getInstance<T>(target: ClassTarget<T>, qual?: symbol, resolution?: ResolutionType): Promise<T> { | ||
this.verifyInitialized(); | ||
@@ -299,11 +304,7 @@ | ||
*/ | ||
registerClass<T>(cls: Class<T>, pconfig: Partial<InjectableConfig<T>>) { | ||
const config = this.getOrCreatePending(pconfig.class!); | ||
registerClass<T>(cls: Class<T>, pconfig: Partial<InjectableConfig<T>> = {}) { | ||
const config = this.getOrCreatePending(pconfig.class ?? cls); | ||
config.class = cls; | ||
config.qualifier = pconfig.qualifier ?? config.qualifier; | ||
if (!config.qualifier) { | ||
config.qualifier = Symbol.for(cls.ᚕid); | ||
this.defaultSymbols.add(config.qualifier); | ||
} | ||
config.qualifier = pconfig.qualifier ?? config.qualifier ?? Symbol.for(cls.ᚕid); | ||
if (pconfig.interfaces) { | ||
@@ -344,3 +345,2 @@ config.interfaces?.push(...pconfig.interfaces); | ||
finalConfig.qualifier = Symbol.for(config.id); | ||
this.defaultSymbols.add(finalConfig.qualifier); | ||
} | ||
@@ -436,2 +436,6 @@ if (config.primary !== undefined) { | ||
if (config.qualifier === Symbol.for(cls.ᚕid)) { | ||
this.defaultSymbols.add(config.qualifier); | ||
} | ||
this.targetToClass.get(targetId)!.set(config.qualifier, classId); | ||
@@ -449,3 +453,3 @@ this.classToTarget.get(classId)!.set(config.qualifier, targetId); | ||
if (config.primary && (classId === targetId || config.factory)) { | ||
this.targetToClass.get(el.ᚕid)!.set(PrimaryCandidateSym, classId); | ||
this.targetToClass.get(el.ᚕid)!.set(PrimaryCandidateⲐ, classId); | ||
} | ||
@@ -463,3 +467,3 @@ } | ||
if (config.primary) { | ||
this.targetToClass.get(parentId)!.set(PrimaryCandidateSym, classId); | ||
this.targetToClass.get(parentId)!.set(PrimaryCandidateⲐ, classId); | ||
} | ||
@@ -475,3 +479,3 @@ | ||
} | ||
this.targetToClass.get(classId)!.set(PrimaryCandidateSym, classId); | ||
this.targetToClass.get(classId)!.set(PrimaryCandidateⲐ, classId); | ||
@@ -484,3 +488,3 @@ // Register primary if only one interface provided and no parent config | ||
} | ||
this.targetToClass.get(intf.ᚕid)!.set(PrimaryCandidateSym, classId); | ||
this.targetToClass.get(intf.ᚕid)!.set(PrimaryCandidateⲐ, classId); | ||
} | ||
@@ -514,3 +518,2 @@ } | ||
super.onReset(); | ||
this.resolved = false; | ||
this.pendingFinalize = []; | ||
@@ -517,0 +520,0 @@ this.instances.clear(); |
import { EnvInit } from '@travetto/base/bin/init'; | ||
export async function invoke(...[mod, cls, method, qualifier]: (string | undefined)[]) { | ||
EnvInit.init({}); | ||
EnvInit.init(); | ||
await (await import('@travetto/base')).PhaseManager.run('init'); | ||
@@ -6,0 +6,0 @@ const inst = await (await import('../src/registry')).DependencyRegistry |
39621