Skip to content

Commit

Permalink
refactor: extract method construct
Browse files Browse the repository at this point in the history
  • Loading branch information
exuanbo committed Oct 21, 2024
1 parent 99f1264 commit 6d43df3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 24 deletions.
42 changes: 29 additions & 13 deletions src/container.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {assert, expectNever} from "./errors";
import {useInjectionContext, withInjectionContext} from "./injection-context";
import {getMetadata, getRegistration} from "./metadata";
import {type ResolvedScope, useInjectionContext, withInjectionContext} from "./injection-context";
import {getMetadata} from "./metadata";
import {
isClassProvider,
isFactoryProvider,
Expand Down Expand Up @@ -82,8 +82,9 @@ export class Container {
const metadata = getMetadata(Class);
const tokens = [Class, ...(metadata.tokens || [])];
tokens.forEach((token) => {
const registration = getRegistration(metadata);
this.registry.set(token, registration);
const provider = metadata.provider;
const options = {scope: metadata.scope};
this.registry.set(token, {provider, options});
});
}
else {
Expand Down Expand Up @@ -119,8 +120,7 @@ export class Container {
this.register(Class);
return this.resolve(Class);
}
const registration = getRegistration(metadata);
return this.createInstance(registration);
return this.construct(Class);
}
}
throwUnregisteredError(tokens);
Expand All @@ -142,13 +142,23 @@ export class Container {
this.register(Class);
return [this.resolve(Class)];
}
const registration = getRegistration(metadata);
return [this.createInstance(registration)];
return [this.construct(Class)];
}
}
throwUnregisteredError(tokens);
}

private construct<T extends object>(Class: Constructor<T>): T {
const metadata = getMetadata(Class);
const provider = metadata.provider;
const resolvedScope = this.resolveScope(metadata.scope);
if (resolvedScope == Scope.Container) {
throw new Error(`unregistered token ${Class.name} cannot be resolved in container scope`);
}
const options = {scope: resolvedScope};
return this.getScopedInstance({provider, options}, () => new Class());
}

private createInstance<T>(registration: Registration<T>): T {
const provider = registration.provider;
if (isClassProvider(provider)) {
Expand Down Expand Up @@ -189,11 +199,7 @@ export class Container {
return dependentRef.current;
}

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

context.resolution.stack.push(provider, {
provider,
Expand Down Expand Up @@ -227,6 +233,16 @@ export class Container {
context.resolution.stack.pop();
}
}

private resolveScope(scope = this.defaultScope): ResolvedScope {
let resolvedScope = scope;
if (resolvedScope == Scope.Inherited) {
const context = useInjectionContext();
const dependentFrame = context?.resolution.stack.peek();
resolvedScope = dependentFrame?.scope || Scope.Transient;
}
return resolvedScope;
}
}

function throwUnregisteredError(tokens: Token[]): never {
Expand Down
13 changes: 2 additions & 11 deletions src/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import type {Provider} from "./provider";
import type {Registration} from "./registry";
import type {ClassProvider} from "./provider";
import type {Scope} from "./scope";
import type {Constructor, Token} from "./token";

export interface Metadata<This extends object = any> {
autoRegister?: boolean;
scope?: Scope;
tokens: Token<This>[];
provider: Provider<This>;
provider: ClassProvider<This>;
}

const metadataRegistry = new WeakMap<Constructor<object>, Metadata>();
Expand All @@ -24,11 +23,3 @@ export function getMetadata<T extends object>(Class: Constructor<T>): Metadata<T
}
return metadata;
}

// @internal
export function getRegistration<T extends object>(metadata: Metadata<T>): Registration<T> {
return {
provider: metadata.provider,
options: {scope: metadata.scope},
};
}

0 comments on commit 6d43df3

Please sign in to comment.