##// END OF EJS Templates
Working on IoC container configuration
cin -
r112:efce7387bfc8 ioc ts support
parent child
Show More
@@ -1,37 +1,41
1 1 import { Constructor } from "../interfaces";
2 2
3 3 export interface InjectOptions {
4 4 lazy?: boolean;
5 5 }
6 6
7 7 type Setter<T = any> = (v: T) => void;
8 8
9 9 type Compatible<T1, T2> = T1 extends T2 ? any : never;
10 10
11 11 type SetterType<T> = T extends (v: infer V) => void ? V : never;
12 12
13 13 type ExtractService<K, S> = K extends keyof S ? S[K] : K;
14 14
15 15 type ExtractDependency<D, S> = D extends { $dependency: infer K } ? D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> : VisitDependency<D, S>;
16 16
17 17 type VisitDependency<D, S> = D extends {} ? { [K in keyof D]: ExtractDependency<D[K], S> } : D;
18 18
19 19 export class Builder<T, S> {
20 20 consume<P extends any[]>(...args: P) {
21 21 return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => {
22 // return constructor;
22 return constructor as typeof constructor & { service: () => T };
23 23 };
24 24 }
25 25
26 26 inject<K extends keyof S>(dependency: K) {
27 27 // K = "bar"
28 28 // M = "setValue"
29 29 // S[K] = Bar
30 30 // T[M] = (value: string) => void
31 31 // P[m] = (value: V) => void
32 32 return <P, M extends keyof (T | P)>(target: P, memberName: M, descriptor: TypedPropertyDescriptor<Compatible<T[M], Setter<S[K]>>>) => {
33 33
34 34 };
35 35 }
36 36
37 cast<T2 extends T>(): Builder<T2, S> {
38 return this as Builder<T2, S>;
37 39 }
40
41 }
@@ -1,28 +1,28
1 1 import { config } from "./config";
2 2
3 3 const service = config.build("barBox");
4 4
5 5 @service.consume(config.dependency("bar"))
6 6 export class Box<T> {
7 7 private _value: T | undefined;
8 8
9 9 constructor(value: T) {
10 10 this._value = value;
11 11 }
12 12
13 13 @service.inject("bar")
14 14 setValue(value: T) {
15 15 this._value = value;
16 16 }
17 17
18 18 setObj(value: object) {
19 19
20 20 }
21 21
22 22 getValue() {
23 23 if (this._value === undefined)
24 24 throw new Error("Trying to get a value from the empty box");
25 25
26 26 return this._value;
27 27 }
28 }
28 } No newline at end of file
@@ -1,67 +1,68
1 1 import { Foo } from "./Foo";
2 2 import { Bar } from "./Bar";
3 3 import { ActivationType } from "../di/interfaces";
4 4 import { Builder } from "../di/Annotations";
5 5 import { Box } from "./Box";
6 6
7 7 interface RegistrationOptions {
8 8 activation?: ActivationType;
9 9 }
10 10
11 11 interface Dependency<K extends keyof any> {
12 12 $dependency: K;
13 13
14 14 lazy?: boolean;
15 15 }
16 16
17 17 interface Lazy<K extends keyof any> extends Dependency<K> {
18 18 lazy: true;
19 19 }
20 20
21 21 type PromiseOrValue<T> = T | PromiseLike<T>;
22 22
23 23 interface ConfigBuilder<S> {
24 24 build<K extends keyof S, T = S[K]>(name: K): Builder<T, S>;
25 25
26 26 dependency<K extends keyof S>(name: K): Dependency<K>;
27 27
28 28 lazy<K extends keyof S>(name: K): Lazy<K>;
29 29
30 30 mapTo<K extends keyof S>(name: K, ctor: () => PromiseOrValue<new (...args: any[]) => S[K]>): ConfigBuilder<S>;
31 31
32 32 }
33 33
34 34 interface ContainerServices {
35 35 barBox: Box<Bar>;
36 36
37 37 foo: Foo;
38 38
39 39 bar: Bar;
40 40
41 41 password: string;
42 42
43 43 user: string;
44 44
45 45 timeout: number;
46 46 }
47 47
48 48 declare function load<M, C extends keyof M>(m: PromiseLike<M>, name: C): () => PromiseLike<M[C]>;
49 49
50 50 const t = {
51 51 barBox: load(import("./Box"), "Box"),
52 52
53 53 foo: async () => (await import("./Bar")).Bar,
54 54
55 55 bar: Bar,
56 56
57 57 password: String,
58 58
59 59 user: String,
60 60
61 61 timeout: Number
62 62 };
63 63
64 declare const bc: typeof Box;
65
66 const x = new bc();
67
64 68 export declare const config: ConfigBuilder<ContainerServices>;
65 config
66 .mapTo("bar", )
67 .mapTo("barBox", ;
General Comments 0
You need to be logged in to leave comments. Login now