# HG changeset patch # User cin # Date 2020-07-13 16:29:26 # Node ID a19ad0acfd39ac871f1ffa38d65275a00ec00514 # Parent b58fedd83580d676d633eee730f296081e3bd064 working on fluent container configuration 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 @@ -55,7 +55,7 @@ interface Declaration dependency(name: K, opts: LazyDependencyOptions): LazyDependencyRegistration; dependency(name: K, opts?: DependencyOptions): DependencyRegistration; - $type

) => any>(target: C, ...params: P): StrictTypeRegistration; + $type) => T>(target: C, ...params: P): StrictTypeRegistration; configure(): Config; } diff --git a/src/main/ts/di/fluent/interfaces.ts b/src/main/ts/di/fluent/interfaces.ts new file mode 100644 --- /dev/null +++ b/src/main/ts/di/fluent/interfaces.ts @@ -0,0 +1,38 @@ +import { primitive } from "../../safe"; +import { ActivationType } from "../interfaces"; + +type ExtractService = K extends keyof S ? S[K] : K; + +type ExtractDependency = D extends { $dependency: infer K } ? + D extends { lazy: true } ? () => ExtractService : ExtractService : + D extends { $type: new (...args: any[]) => infer I } ? I : + D extends { $factory: (...args: any[]) => infer R } ? R : + WalkDependencies; + +type WalkDependencies = D extends primitive ? D : + { [K in keyof D]: ExtractDependency }; + +export interface TypeBuilder { + type

) => T>( + target: C, ...params: P): ConstructorBuilder; + factory

) => T>( + target: F, ...params: P): FactoryBuilder; +} + +export interface ServiceBuilder { + override(name: K, builder: S[K] | ((t: TypeBuilder) => any)): this; + activate(activation: ActivationType): this; + inject(member: T[M] extends (...params: ExtractDependency) => any ? M : never, ...params: P): this; +} + +export interface ConstructorBuilder any, S extends object> extends ServiceBuilder, S> { + $type: C; +} + +export interface FactoryBuilder any, S extends object> extends ServiceBuilder, S> { + $factory: F; +} + +export interface ConfigBuilder { + register(name: K, builder: S[K] | ((t: TypeBuilder) => any)): ConfigBuilder>; +} 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 @@ -27,6 +27,10 @@ export class Bar { this._v = _opts.foo; } + setName(name: string) { + + } + getFoo() { if (this._v === undefined) throw new Error("The foo isn't set"); 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 @@ -2,22 +2,29 @@ import { configure, dependency, Services import { Foo } from "./Foo"; import { Bar } from "./Bar"; import { Box } from "./Box"; - +import { declare } from "../di/Annotations"; +import { ConfigBuilder, TypeBuilder } from "../di/fluent/interfaces"; -export const config = configure() - .register("bar", { $from: import("./Bar"), service: "service" }) +export declare function build(): TypeBuilder; + +export declare const config: ConfigBuilder; +config + //.register("bar", { $from: import("./Bar"), service: "service" }) // .register("box", { $from: import("./Box") }) .register("host", "example.com") // .registerType("bar2", Bar, [{ foo: dependency("foo"), host: "" }]); - .register("bar2", $type(Bar, + .register("bar2", s => s.type(Bar, { - foo: $type(Foo) - .override("host", "foo.example.com") - .inject("setName", dependency("host")) + foo: build().type(Foo) .activate("context"), - host: "" + nested: { lazy: dependency("foo", {lazy: true}) }, + host: dependency("host") }, "") + .inject("setName", dependency("host")) ) - .registerType("box", Box, dependency("bar")); + .register("box", s => s + .type(Box, dependency("bar")) + .activate("context") + ); 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 @@ -53,6 +53,7 @@ test("Container configure/resolve tests" foo: Foo; box: Bar; bar: Bar; + db: any; }>(); await container.configure({ @@ -69,13 +70,13 @@ test("Container configure/resolve tests" bar: { $type: Bar, - params: { + params: [{ db: { provider: { $dependency: "db" } } - } + }] } }); t.pass("should configure from js object");