diff --git a/src/main/ts/di/Annotations.ts b/src/main/ts/di/Annotations.ts --- a/src/main/ts/di/Annotations.ts +++ b/src/main/ts/di/Annotations.ts @@ -6,27 +6,20 @@ export interface InjectOptions { type Setter = (v: T) => void; -type Injector = { - [k in keyof T]: Setter; -}; - type Compatible = T1 extends T2 ? any : never; type SetterType = T extends (v: infer V) => void ? V : never; -type Tuple = Parameters<(...args: T[]) => void>; +type ExtractService = K extends keyof S ? S[K] : K; -interface Newable { - new (...params: A): T; - prototype: T; -} +type ExtractDependency = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService : ExtractService : VisitDependency; -type MapTuple = { [K in keyof A] : K extends number ? T[ A[K] ] : A[K] }; +type VisitDependency = D extends {} ? { [K in keyof D]: ExtractDependency } : D; export class Builder { - provides() { - return >(constructor: C) => { - return constructor; + consume

(...args: P) { + return ) => T>(constructor: C) => { + // return constructor; }; } @@ -41,10 +34,4 @@ export class Builder { }; } - dependencies(...deps: D) { - return >(constructor: MapTuple extends ConstructorParameters ? C : never) => { - return constructor; - } ; - } - } diff --git a/src/main/ts/interfaces.ts b/src/main/ts/interfaces.ts --- a/src/main/ts/interfaces.ts +++ b/src/main/ts/interfaces.ts @@ -55,7 +55,7 @@ export interface IActivatable { * can be activated and manages the active state of the * component */ - setActivationController(controller: IActivationController); + setActivationController(controller: IActivationController): void; /** * Gets the current activation controller for this component diff --git a/src/test/ts/mock/Bar.ts b/src/test/ts/mock/Bar.ts --- a/src/test/ts/mock/Bar.ts +++ b/src/test/ts/mock/Bar.ts @@ -1,18 +1,33 @@ import { Foo } from "./Foo"; +import { config } from "./config"; -export class Bar { - name = "bar"; +const service = config.build("bar"); - foo: Foo | undefined; +@service.consume({ + f: config.dependency("foo"), + nested: { + lazy: config.lazy("foo") + } +}) +export class Bar { + barName = "bar"; - constructor(_opts?: { foo?: Foo; }) { - if (_opts && _opts.foo) - this.foo = _opts.foo; + _v: Foo | undefined; + + constructor(_opts: { + f: Foo; + nested: { + lazy: () => Foo + } + }) { + + if (_opts && _opts.f) + this._v = _opts.f; } getFoo() { - if (this.foo === undefined) + if (this._v === undefined) throw new Error("The foo isn't set"); - return this.foo; + return this._v; } } diff --git a/src/test/ts/mock/Box.ts b/src/test/ts/mock/Box.ts --- a/src/test/ts/mock/Box.ts +++ b/src/test/ts/mock/Box.ts @@ -1,8 +1,8 @@ import { config } from "./config"; -const service = config.service("barBox"); +const service = config.build("barBox"); -@service.provides() +@service.consume(config.dependency("bar")) export class Box { private _value: T | undefined; @@ -15,7 +15,6 @@ export class Box { this._value = value; } - @service.inject("foo") setObj(value: object) { } @@ -26,4 +25,4 @@ export class Box { return this._value; } -} \ No newline at end of file +} diff --git a/src/test/ts/mock/Foo.ts b/src/test/ts/mock/Foo.ts --- a/src/test/ts/mock/Foo.ts +++ b/src/test/ts/mock/Foo.ts @@ -1,3 +1,3 @@ export class Foo { - name = "foo"; + fooName = "foo"; } diff --git a/src/test/ts/mock/config.ts b/src/test/ts/mock/config.ts --- a/src/test/ts/mock/config.ts +++ b/src/test/ts/mock/config.ts @@ -8,8 +8,27 @@ interface RegistrationOptions { activation?: ActivationType; } +interface Dependency { + $dependency: K; + + lazy?: boolean; +} + +interface Lazy extends Dependency { + lazy: true; +} + +type PromiseOrValue = T | PromiseLike; + interface ConfigBuilder { - service(name: K): Builder; + build(name: K): Builder; + + dependency(name: K): Dependency; + + lazy(name: K): Lazy; + + mapTo(name: K, ctor: () => PromiseOrValue S[K]>): ConfigBuilder; + } interface ContainerServices { @@ -26,4 +45,23 @@ interface ContainerServices { timeout: number; } +declare function load(m: PromiseLike, name: C): () => PromiseLike; + +const t = { + barBox: load(import("./Box"), "Box"), + + foo: async () => (await import("./Bar")).Bar, + + bar: Bar, + + password: String, + + user: String, + + timeout: Number +}; + export declare const config: ConfigBuilder; +config + .mapTo("bar", ) + .mapTo("barBox", ; diff --git a/src/test/ts/tests/ContainerTests.ts b/src/test/ts/tests/ContainerTests.ts --- a/src/test/ts/tests/ContainerTests.ts +++ b/src/test/ts/tests/ContainerTests.ts @@ -89,5 +89,5 @@ test("Load configuration from module", a const b1 = container.resolve("bar") as Bar; t.assert(!isNull(b1), "bar should not be null"); - t.assert(!isNull(b1.foo), "bar.foo should not be null"); + t.assert(!isNull(b1._v), "bar.foo should not be null"); });