Skip to content

Commit

Permalink
refactor: some renaming
Browse files Browse the repository at this point in the history
  • Loading branch information
exuanbo committed Oct 17, 2024
1 parent 3278591 commit 029896d
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 38 deletions.
55 changes: 31 additions & 24 deletions src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
isValueProvider,
type Provider,
} from "./provider";
import {type Options, type Registration, Registry} from "./registry";
import {type Registration, type RegistrationOptions, Registry} from "./registry";
import {Scope} from "./scope";
import {type Constructor, isConstructor, type Token, type TokenList} from "./token";
import {KeyedStack} from "./utils/keyed-stack";
Expand All @@ -22,8 +22,8 @@ export class Container {
readonly parent?: Container;
readonly registry: Registry;

defaultScope: Scope;
autoRegister: boolean;
defaultScope: Scope;

constructor(options?: ContainerOptions);
constructor({
Expand Down Expand Up @@ -61,11 +61,15 @@ export class Container {
}

register<Instance extends object>(Class: Constructor<Instance>): this;
register<Value>(token: Token<Value>, provider: Provider<Value>, options?: Options): this;
register<Value>(
token: Token<Value>,
provider: Provider<Value>,
options?: RegistrationOptions,
): this;
register<Value>(
...args:
| [Constructor<Value & object>]
| [Token<Value>, Provider<Value>, Options?]
| [Token<Value>, Provider<Value>, RegistrationOptions?]
): this {
if (args.length == 1) {
const [Class] = args;
Expand All @@ -83,10 +87,7 @@ export class Container {
const Class = provider.useClass;
const metadata = getMetadata(Class);
provider = metadata.provider;
options = {
scope: metadata.scope,
...options,
};
options = {scope: metadata.scope, ...options};
}
this.registry.set(token, {provider, options});
}
Expand Down Expand Up @@ -143,19 +144,20 @@ export class Container {
}

private resolveValue<Value>(registration: Registration<Value>): Value {
if (isClassProvider(registration.provider)) {
const Class = registration.provider.useClass;
const provider = registration.provider;
if (isClassProvider(provider)) {
const Class = provider.useClass;
return this.resolveScopedInstance(registration, () => new Class());
}
else if (isFactoryProvider(registration.provider)) {
const factory = registration.provider.useFactory;
else if (isFactoryProvider(provider)) {
const factory = provider.useFactory;
return this.resolveScopedInstance(registration, factory);
}
else if (isValueProvider(registration.provider)) {
const value = registration.provider.useValue;
else if (isValueProvider(provider)) {
const value = provider.useValue;
return value;
}
expectNever(registration.provider);
expectNever(provider);
}

private resolveScopedInstance<T>(registration: Registration<T>, instantiate: () => T): T {
Expand All @@ -172,21 +174,25 @@ export class Container {
}, () => this.resolveScopedInstance(registration, instantiate));
}

if (context.resolution.stack.has(registration.provider)) {
if (context.resolution.dependents.has(registration.provider)) {
return context.resolution.dependents.get(registration.provider);
const provider = registration.provider;
const options = registration.options;

if (context.resolution.stack.has(provider)) {
const dependentRef = context.resolution.dependents.get(provider);
if (dependentRef) {
return dependentRef.current;
}
assert(false, ErrorMessage.CircularDependency);
}

let resolvedScope = registration.options?.scope || this.defaultScope;
let resolvedScope = options?.scope || this.defaultScope;
if (resolvedScope == Scope.Inherited) {
const dependentFrame = context.resolution.stack.peek();
resolvedScope = dependentFrame?.scope || Scope.Transient;
}

context.resolution.stack.push(registration.provider, {
provider: registration.provider,
context.resolution.stack.push(provider, {
provider,
scope: resolvedScope,
});
try {
Expand All @@ -199,11 +205,12 @@ export class Container {
return instance;
}
else if (resolvedScope == Scope.Resolution) {
if (context.resolution.instances.has(registration.provider)) {
return context.resolution.instances.get(registration.provider);
const instanceRef = context.resolution.instances.get(provider);
if (instanceRef) {
return instanceRef.current;
}
const instance = instantiate();
context.resolution.instances.set(registration.provider, instance);
context.resolution.instances.set(provider, {current: instance});
return instance;
}
else if (resolvedScope == Scope.Transient) {
Expand Down
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ export type {ClassDecorator, ClassFieldDecorator, ClassFieldInitializer} from ".
export {AutoRegister, Inject, Injectable, InjectAll, Scoped} from "./decorators";
export {ErrorMessage} from "./errors";
export {inject, injectAll} from "./inject";
export type {InstanceRef} from "./instance";
export type {ClassProvider, FactoryProvider, Provider, ValueProvider} from "./provider";
export type {Cache, Options, Registration, Registry} from "./registry";
export type {Registration, RegistrationOptions, Registry} from "./registry";
export {Build, Value} from "./registry";
export {Scope} from "./scope";
export type {Constructor, Token, TokenList} from "./token";
Expand Down
5 changes: 3 additions & 2 deletions src/inject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ export namespace inject {
assert(context, ErrorMessage.InjectOutsideOfContext);
const currentFrame = context.resolution.stack.peek();
assert(currentFrame, ErrorMessage.InvariantViolation);
context.resolution.dependents.set(currentFrame.provider, thisArg);
const provider = currentFrame.provider;
context.resolution.dependents.set(provider, {current: thisArg});
try {
return inject(...tokens);
}
finally {
context.resolution.dependents.delete(currentFrame.provider);
context.resolution.dependents.delete(provider);
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/injection-context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {Container} from "./container";
import type {InstanceRef} from "./instance";
import type {Provider} from "./provider";
import type {Scope} from "./scope";
import {createContext} from "./utils/context";
Expand All @@ -10,12 +11,12 @@ export interface InjectionContext {
}

export interface Resolution {
stack: KeyedStack<Provider, Frame>;
instances: Map<Provider, any>;
dependents: Map<Provider, any>;
stack: KeyedStack<Provider, ResolutionFrame>;
instances: Map<Provider, InstanceRef>;
dependents: Map<Provider, InstanceRef>;
}

export interface Frame {
export interface ResolutionFrame {
scope: ResolvedScope;
provider: Provider;
}
Expand Down
3 changes: 3 additions & 0 deletions src/instance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface InstanceRef<T = any> {
readonly current: T;
}
11 changes: 4 additions & 7 deletions src/registry.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import {assert} from "./errors";
import {ErrorMessage} from "./errors";
import type {InstanceRef} from "./instance";
import {NullProvider, type Provider, UndefinedProvider} from "./provider";
import {Scope} from "./scope";
import {type Token, Type} from "./token";

export interface Registration<T = any> {
cache?: Cache<T>;
options?: Options;
options?: RegistrationOptions;
cache?: InstanceRef<T>;
provider: Provider<T>;
}

export interface Cache<T> {
current: T;
}

export interface Options {
export interface RegistrationOptions {
scope?: Scope;
}

Expand Down

0 comments on commit 029896d

Please sign in to comment.