From 0d2e0ee11b64654a8a2b8af88c16b9dcdb244743 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 15 Nov 2021 22:35:22 -0600 Subject: [PATCH] Fix defaultValue --- package.json | 2 +- src/decorators/inject.spec.ts | 15 ++++++++++++++ src/decorators/inject.ts | 38 +++++++++++++++++------------------ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 62aa653..9027efb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@technove/inject", "description": "Dependency injection for TypeScript", - "version": "0.1.6", + "version": "0.1.7", "author": "PaulBGD", "license": "MIT", "scripts": { diff --git a/src/decorators/inject.spec.ts b/src/decorators/inject.spec.ts index db819c5..efd2a3c 100644 --- a/src/decorators/inject.spec.ts +++ b/src/decorators/inject.spec.ts @@ -4,6 +4,7 @@ import { Inject } from "./inject"; import { getInjectedData } from "../injector"; import { expect } from "chai"; import { it } from "mocha"; +import { Container } from "../container"; describe("@Inject", () => { it("adds injected data to the class", () => { @@ -31,4 +32,18 @@ describe("@Inject", () => { } }).to.throw("Cannot inject self in constructor"); }); + + it("supports reading the default value", () => { + class A { + @Inject( + (c, field) => + field.fieldType === "property" && field.defaultValue + ) + val = 5; + } + + const container = new Container(); + const a = container.get(A); + expect(a.val).to.be.equal(5); + }); }); diff --git a/src/decorators/inject.ts b/src/decorators/inject.ts index 695cb5e..4cc8bcb 100644 --- a/src/decorators/inject.ts +++ b/src/decorators/inject.ts @@ -9,6 +9,8 @@ export interface InjectProps { provider?: FieldProvider; } +const NO_VALUE = Symbol("no-value"); + export const Inject: ( props?: InjectProps | FieldProvider ) => PropertyDecorator & ParameterDecorator = @@ -58,9 +60,7 @@ export const Inject: ( ); if (parameterIndex === undefined) { - const defaultValue = (target as any)[propertyName]; - - let val: any = undefined; + let val: any = NO_VALUE; const provider: Provider = ( container: Container, target: Object @@ -68,12 +68,27 @@ export const Inject: ( const field: FieldProperty = { fieldType: "property", name: propertyName as string, - defaultValue, + defaultValue: (target as any)[propertyName], target, type: propertyType, getValue: () => val, }; + Object.defineProperty(target, propertyName, { + get() { + if (val === NO_VALUE) { + throw new Error( + `Property ${propertyName} has not been injected` + ); + } + return val; + }, + + set(newVal: never) { + val = newVal; + }, + }); + const retrieved = retrievalProvider(container, field); if (retrieved instanceof Promise) { return retrieved.then((newVal) => (val = newVal)); @@ -82,21 +97,6 @@ export const Inject: ( } }; data.properties.push(provider); - - Object.defineProperty(target, propertyName, { - get() { - if (val === undefined) { - throw new Error( - `Property ${propertyName} has not been injected` - ); - } - return val; - }, - - set(newVal: never) { - val = newVal; - }, - }); } else { if (propertyType === target) { throw new Error("Cannot inject self in constructor");