| @@ -0,0 +1,38 | |||||
|
|
1 | import { primitive } from "../../safe"; | |||
|
|
2 | import { ActivationType } from "../interfaces"; | |||
|
|
3 | ||||
|
|
4 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; | |||
|
|
5 | ||||
|
|
6 | type ExtractDependency<D, S> = D extends { $dependency: infer K } ? | |||
|
|
7 | D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> : | |||
|
|
8 | D extends { $type: new (...args: any[]) => infer I } ? I : | |||
|
|
9 | D extends { $factory: (...args: any[]) => infer R } ? R : | |||
|
|
10 | WalkDependencies<D, S>; | |||
|
|
11 | ||||
|
|
12 | type WalkDependencies<D, S> = D extends primitive ? D : | |||
|
|
13 | { [K in keyof D]: ExtractDependency<D[K], S> }; | |||
|
|
14 | ||||
|
|
15 | export interface TypeBuilder<T, S extends object> { | |||
|
|
16 | type<P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>( | |||
|
|
17 | target: C, ...params: P): ConstructorBuilder<C, S>; | |||
|
|
18 | factory<P extends any[], F extends (...args: ExtractDependency<P, S>) => T>( | |||
|
|
19 | target: F, ...params: P): FactoryBuilder<F, S>; | |||
|
|
20 | } | |||
|
|
21 | ||||
|
|
22 | export interface ServiceBuilder<T, S extends object> { | |||
|
|
23 | override<K extends keyof S>(name: K, builder: S[K] | ((t: TypeBuilder<S[K], S>) => any)): this; | |||
|
|
24 | activate(activation: ActivationType): this; | |||
|
|
25 | inject<M extends keyof T, P extends any[]>(member: T[M] extends (...params: ExtractDependency<P, S>) => any ? M : never, ...params: P): this; | |||
|
|
26 | } | |||
|
|
27 | ||||
|
|
28 | export interface ConstructorBuilder<C extends new (...args: any[]) => any, S extends object> extends ServiceBuilder<InstanceType<C>, S> { | |||
|
|
29 | $type: C; | |||
|
|
30 | } | |||
|
|
31 | ||||
|
|
32 | export interface FactoryBuilder<F extends (...args: any[]) => any, S extends object> extends ServiceBuilder<ReturnType<F>, S> { | |||
|
|
33 | $factory: F; | |||
|
|
34 | } | |||
|
|
35 | ||||
|
|
36 | export interface ConfigBuilder<S extends object, Y extends keyof S = keyof S> { | |||
|
|
37 | register<K extends Y>(name: K, builder: S[K] | ((t: TypeBuilder<S[K], S>) => any)): ConfigBuilder<S, Exclude<Y, K>>; | |||
|
|
38 | } | |||
| @@ -55,7 +55,7 interface Declaration<S extends object> | |||||
| 55 | dependency<K extends keyof S>(name: K, opts: LazyDependencyOptions<S[K]>): LazyDependencyRegistration<S, K>; |
|
55 | dependency<K extends keyof S>(name: K, opts: LazyDependencyOptions<S[K]>): LazyDependencyRegistration<S, K>; | |
| 56 | dependency<K extends keyof S>(name: K, opts?: DependencyOptions<S[K]>): DependencyRegistration<S, K>; |
|
56 | dependency<K extends keyof S>(name: K, opts?: DependencyOptions<S[K]>): DependencyRegistration<S, K>; | |
| 57 |
|
57 | |||
| 58 |
$type<P extends any[], C extends new (...args: ExtractDependency<P, S>) => |
|
58 | $type<T, P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>(target: C, ...params: P): StrictTypeRegistration<C, S>; | |
| 59 |
|
59 | |||
| 60 | configure(): Config<S>; |
|
60 | configure(): Config<S>; | |
| 61 | } |
|
61 | } | |
| @@ -27,6 +27,10 export class Bar { | |||||
| 27 | this._v = _opts.foo; |
|
27 | this._v = _opts.foo; | |
| 28 | } |
|
28 | } | |
| 29 |
|
29 | |||
|
|
30 | setName(name: string) { | |||
|
|
31 | ||||
|
|
32 | } | |||
|
|
33 | ||||
| 30 | getFoo() { |
|
34 | getFoo() { | |
| 31 | if (this._v === undefined) |
|
35 | if (this._v === undefined) | |
| 32 | throw new Error("The foo isn't set"); |
|
36 | throw new Error("The foo isn't set"); | |
| @@ -2,22 +2,29 import { configure, dependency, Services | |||||
| 2 | import { Foo } from "./Foo"; |
|
2 | import { Foo } from "./Foo"; | |
| 3 | import { Bar } from "./Bar"; |
|
3 | import { Bar } from "./Bar"; | |
| 4 | import { Box } from "./Box"; |
|
4 | import { Box } from "./Box"; | |
| 5 |
|
5 | import { declare } from "../di/Annotations"; | ||
|
|
6 | import { ConfigBuilder, TypeBuilder } from "../di/fluent/interfaces"; | |||
| 6 |
|
7 | |||
| 7 | export const config = configure() |
|
8 | export declare function build<T>(): TypeBuilder<T, Services>; | |
| 8 | .register("bar", { $from: import("./Bar"), service: "service" }) |
|
9 | ||
|
|
10 | export declare const config: ConfigBuilder<Services>; | |||
|
|
11 | config | |||
|
|
12 | //.register("bar", { $from: import("./Bar"), service: "service" }) | |||
| 9 | // .register("box", { $from: import("./Box") }) |
|
13 | // .register("box", { $from: import("./Box") }) | |
| 10 |
|
|
14 | .register("host", "example.com") | |
| 11 | // .registerType("bar2", Bar, [{ foo: dependency("foo"), host: "" }]); |
|
15 | // .registerType("bar2", Bar, [{ foo: dependency("foo"), host: "" }]); | |
| 12 |
.register("bar2", |
|
16 | .register("bar2", s => s.type(Bar, | |
| 13 | { |
|
17 | { | |
| 14 |
foo: |
|
18 | foo: build().type(Foo) | |
| 15 | .override("host", "foo.example.com") |
|
|||
| 16 | .inject("setName", dependency("host")) |
|
|||
| 17 | .activate("context"), |
|
19 | .activate("context"), | |
| 18 | host: "" |
|
20 | nested: { lazy: dependency("foo", {lazy: true}) }, | |
|
|
21 | host: dependency("host") | |||
| 19 | }, |
|
22 | }, | |
| 20 | "") |
|
23 | "") | |
|
|
24 | .inject("setName", dependency("host")) | |||
| 21 | ) |
|
25 | ) | |
| 22 | .registerType("box", Box, dependency("bar")); |
|
26 | .register("box", s => s | |
|
|
27 | .type(Box, dependency("bar")) | |||
|
|
28 | .activate("context") | |||
|
|
29 | ); | |||
| 23 |
|
30 | |||
| @@ -53,6 +53,7 test("Container configure/resolve tests" | |||||
| 53 | foo: Foo; |
|
53 | foo: Foo; | |
| 54 | box: Bar; |
|
54 | box: Bar; | |
| 55 | bar: Bar; |
|
55 | bar: Bar; | |
|
|
56 | db: any; | |||
| 56 | }>(); |
|
57 | }>(); | |
| 57 |
|
58 | |||
| 58 | await container.configure({ |
|
59 | await container.configure({ | |
| @@ -69,13 +70,13 test("Container configure/resolve tests" | |||||
| 69 |
|
70 | |||
| 70 | bar: { |
|
71 | bar: { | |
| 71 | $type: Bar, |
|
72 | $type: Bar, | |
| 72 | params: { |
|
73 | params: [{ | |
| 73 | db: { |
|
74 | db: { | |
| 74 | provider: { |
|
75 | provider: { | |
| 75 | $dependency: "db" |
|
76 | $dependency: "db" | |
| 76 | } |
|
77 | } | |
| 77 | } |
|
78 | } | |
| 78 | } |
|
79 | }] | |
| 79 | } |
|
80 | } | |
| 80 | }); |
|
81 | }); | |
| 81 | t.pass("should configure from js object"); |
|
82 | t.pass("should configure from js object"); | |
General Comments 0
You need to be logged in to leave comments.
Login now
