Skip to content

Commit

Permalink
Fix DI bug where value provider was incorrectly indentified
Browse files Browse the repository at this point in the history
as a constructor when useValue is undefined
  • Loading branch information
lennykean committed Jan 31, 2021
1 parent 41741b9 commit aa4023c
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 17 deletions.
1 change: 1 addition & 0 deletions common/mod.ts
@@ -1 +1,2 @@
export * from "./helpers.ts";
export * from "./multikey-map.ts";
70 changes: 70 additions & 0 deletions common/multikey-map.ts
@@ -0,0 +1,70 @@
export class MultikeyMap<TKey1, TKey2, TValue> {
readonly #map = new Map<TKey1, Map<TKey2, TValue>>();
constructor(entries?: [TKey1, TKey2, TValue][]) {
entries?.forEach(([key1, key2, value]) => this.set(key1, key2, value));
}
get size() {
return Array.from(this.#map.values()).reduce(
(accum, map) => accum + map.size,
0
);
}
has(key1: TKey1, key2: TKey2) {
const map = this.#map.get(key1);
if (!map) {
return false;
}
return this.#map.get(key1)?.has(key2);
}
get(key1: TKey1, key2: TKey2) {
if (this.#map.has(key1)) {
return this.#map.get(key1)?.get(key2);
}
}
set(key1: TKey1, key2: TKey2, value: TValue) {
let map = this.#map.get(key1);
if (!map) {
map = new Map();
this.#map.set(key1, map);
}
map.set(key2, value);
}
delete(key1: TKey1, key2: TKey2) {
const map = this.#map.get(key1);
if (!map) {
return;
}
map.delete(key2);
}
clear() {
this.#map.clear();
}
*entries(): Generator<[TKey1, TKey2, TValue]> {
for (const [key1, map] of this.#map.entries()) {
for (const [key2, value] of map) {
yield [key1, key2, value];
}
}
}
*keys(): Generator<[TKey1, TKey2]> {
for (const [key1, map] of this.#map.entries()) {
for (const [key2, _] of map) {
yield [key1, key2];
}
}
}
*values(): Generator<TValue> {
for (const [_, map] of this.#map.entries()) {
for (const [_, value] of map) {
yield value;
}
}
}
forEach(callbackFn: (value: TValue, key1: TKey1, key2: TKey2) => void) {
for (const [key1, map] of this.#map.entries()) {
for (const [key2, value] of map) {
callbackFn(value, key1, key2);
}
}
}
}
9 changes: 5 additions & 4 deletions core/module-metadata.ts
Expand Up @@ -54,22 +54,23 @@ export interface ExtendedModuleMetadata extends ModuleMetadata {
export type DynamicModule = Omit<ExtendedModuleMetadata, "params" | "props">;

export function isProvider(arg: unknown): arg is Provider {
return !!(arg as Provider).provide;
return Object.prototype.hasOwnProperty.call(arg, "provide");
}
export function isValueProvider(arg: Provider): arg is ValueProvider {
return !!(arg as ValueProvider).useValue;
return Object.prototype.hasOwnProperty.call(arg, "useValue");
}
export function isFactoryProvider(arg: Provider): arg is FactoryProvider {
return !!(arg as FactoryProvider).useFactory;
return Object.prototype.hasOwnProperty.call(arg, "useFactory");
}
export function isClassProvider(arg: Provider): arg is ClassProvider {
return !!(arg as ClassProvider).useClass;
return Object.prototype.hasOwnProperty.call(arg, "useClass");
}
export function isConstructorProvider(
arg: Provider
): arg is ConstructorProvider {
return (
isProvider(arg) &&
typeof arg.provide === "function" &&
!isClassProvider(arg) &&
!isFactoryProvider(arg) &&
!isValueProvider(arg)
Expand Down
4 changes: 0 additions & 4 deletions core/platform.ts
Expand Up @@ -14,10 +14,6 @@ import { MvFilter } from "./mv-filter.ts";
import { MvMiddleware } from "./mv-middleware.ts";
import { ServerController } from "./server-controller.ts";

function isCustomScope(scopeIdentifier: unknown) {
return Object.values(Scope).every((scope) => scope !== scopeIdentifier);
}

export function platformMomentum() {
return new MomentumPlatform(DiContainer.root().createChild("platform"));
}
Expand Down
1 change: 1 addition & 0 deletions di/deps.ts
@@ -1 +1,2 @@
export * from "../common/mod.ts";
export * from "https://deno.land/x/deno_events@0.1.1/mod.ts";
18 changes: 9 additions & 9 deletions di/di-container.ts
Expand Up @@ -98,8 +98,8 @@ export class DiContainer {
#name: string;
#parent?: DiContainer;
#events = new EventEmitter<{
clearGraph(): void;
changeGraph(type: TypeIdentifier): void;
invalidateGraph(): void;
partialInvalidateGraph(type: TypeIdentifier): void;
}>();
#imports = new Map<TypeIdentifier, DiContainer>();
#aliases = new Map<TypeIdentifier, TypeIdentifier>();
Expand All @@ -115,10 +115,10 @@ export class DiContainer {
this.#parent = parent;
this.#name = name;
if (this.#parent) {
this.#parent.#events.on("changeGraph", (identifier) =>
this.#parent.#events.on("partialInvalidateGraph", (identifier) =>
this.partialInvalidateDependencyGraph(identifier)
);
this.#parent.#events.on("clearGraph", () =>
this.#parent.#events.on("invalidateGraph", () =>
this.invalidateDependencyGraph()
);
}
Expand Down Expand Up @@ -332,7 +332,7 @@ export class DiContainer {
private invalidateDependencyGraph() {
if (this.#dependencyGraph.size > 0) {
this.#dependencyGraph.clear();
this.#events.emit("clearGraph");
this.#events.emit("invalidateGraph");
}
}

Expand All @@ -342,29 +342,29 @@ export class DiContainer {
for (const trimIdentifier of identifiers) {
if (graphIdentifier === trimIdentifier) {
graph.delete(trimIdentifier);
this.#events.emit("changeGraph", trimIdentifier);
this.#events.emit("partialInvalidateGraph", trimIdentifier);
continue;
}
if (node.kind == "type") {
for (const param of node.params ?? []) {
if (param.node.identifier === trimIdentifier) {
graph.delete(graphIdentifier);
this.#events.emit("changeGraph", trimIdentifier);
this.#events.emit("partialInvalidateGraph", trimIdentifier);
break;
}
}
for (const [_, prop] of Object.entries(node.props ?? {})) {
if (prop.node.identifier === trimIdentifier) {
graph.delete(graphIdentifier);
this.#events.emit("changeGraph", trimIdentifier);
this.#events.emit("partialInvalidateGraph", trimIdentifier);
break;
}
}
} else if (node.kind == "factory") {
for (const param of node.params ?? []) {
if (param.node.identifier === trimIdentifier) {
graph.delete(graphIdentifier);
this.#events.emit("changeGraph", trimIdentifier);
this.#events.emit("partialInvalidateGraph", trimIdentifier);
break;
}
}
Expand Down

0 comments on commit aa4023c

Please sign in to comment.