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