##// END OF EJS Templates
sync
cin -
r126:142c5f6dc2b5 ioc ts support
parent child
Show More
@@ -1,79 +1,62
1 import { primitive } from "../safe";
1 import { primitive } from "../safe";
2 import { TypeRegistration, DependencyRegistration, LazyDependencyRegistration, Registration, StrictTypeRegistration } from "./Configuration";
2 import { TypeRegistration, DependencyRegistration, LazyDependencyRegistration, Registration, StrictTypeRegistration } from "./Configuration";
3
3
4 export interface InjectOptions {
4 export interface InjectOptions {
5 lazy?: boolean;
5 lazy?: boolean;
6 }
6 }
7
7
8 type Compatible<T1, T2> = T2 extends T1 ? any : never;
8 type Compatible<T1, T2> = T2 extends T1 ? any : never;
9
9
10 type ExtractService<K, S> = K extends keyof S ? S[K] : K;
10 type ExtractService<K, S> = K extends keyof S ? S[K] : K;
11
11
12 type ExtractDependency<D, S> = D extends { $dependency: infer K } ?
12 type ExtractDependency<D, S> = D extends { $dependency: infer K } ?
13 D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> :
13 D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> :
14 D extends { $type: new (...args: any[]) => infer I } ? I :
14 D extends { $type: new (...args: any[]) => infer I } ? I :
15 WalkDependencies<D, S>;
15 WalkDependencies<D, S>;
16
16
17 type WalkDependencies<D, S> = D extends primitive ? D :
17 type WalkDependencies<D, S> = D extends primitive ? D :
18 { [K in keyof D]: ExtractDependency<D[K], S> };
18 { [K in keyof D]: ExtractDependency<D[K], S> };
19
19
20 export class Builder<T, S extends object> {
20 export class Builder<T, S extends object> {
21 declare<P extends any[]>(...args: P) {
21 declare<P extends any[]>(...args: P) {
22 return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => {
22 return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => {
23
23
24 };
24 };
25 }
25 }
26
26
27 inject<P extends any[]>(...args: P) {
27 inject<P extends any[]>(...args: P) {
28 return <X extends { [m in M]: (...args: any) => any }, M extends keyof (T | X)>(
28 return <X extends { [m in M]: (...args: any) => any }, M extends keyof (T | X)>(
29 target: X,
29 target: X,
30 memberName: M,
30 memberName: M,
31 descriptor: TypedPropertyDescriptor<Compatible<(...args: ExtractDependency<P, S>) => any, T[M]>>
31 descriptor: TypedPropertyDescriptor<Compatible<(...args: ExtractDependency<P, S>) => any, T[M]>>
32 ) => {
32 ) => {
33
33
34 };
34 };
35 }
35 }
36
36
37 getDescriptor(): TypeRegistration<new () => T, S> {
37 getDescriptor(): TypeRegistration<new () => T, S> {
38 throw new Error();
38 throw new Error();
39 }
39 }
40
40
41 }
41 }
42
42
43 export interface DependencyOptions<T> {
43 export interface DependencyOptions<T> {
44 optional?: boolean;
44 optional?: boolean;
45 default?: T;
45 default?: T;
46 }
46 }
47
47
48 export interface LazyDependencyOptions<T> extends DependencyOptions<T> {
48 export interface LazyDependencyOptions<T> extends DependencyOptions<T> {
49 lazy: true;
49 lazy: true;
50 }
50 }
51
51
52 interface Declaration<S extends object> {
52 interface Declaration<S extends object> {
53 define<T>(): Builder<T, S>;
53 define<T>(): Builder<T, S>;
54
54
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<T, P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>(target: C, ...params: P): StrictTypeRegistration<C, S>;
58 $type<T, P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>(target: C, ...params: P): StrictTypeRegistration<C, S>;
59
60 configure(): Config<S>;
61 }
59 }
62
60
63 type ServiceModule<T, S extends object, M extends string = "service"> = {
64 [m in M]: Builder<T, S>;
65 };
66
67 type PromiseOrValue<T> = PromiseLike<T> | T;
68
69
61
70 export interface Config<S extends object, Y extends keyof S = keyof S> {
71 register<K extends Y>(name: K, m: { $from: Promise<ServiceModule<S[K], S>> }): Config<S, Exclude<Y, K>>;
72 register<K extends Y, M extends string>(name: K, m: { $from: Promise<ServiceModule<S[K], S, M>>, service: M }): Config<S, Exclude<Y, K>>;
73
74 register<K extends Y>(name: K, m: Registration<S[K], S>): Config<S, Exclude<Y, K>>;
75 registerType<K extends Y, P extends any[]>(
76 name: K, $type: new (...args: ExtractDependency<P, S>) => S[K], ...params: P): Config<S, Exclude<Y, K>>;
77 }
78
79 export declare function declare<S extends object>(): Declaration<S>;
62 export declare function declare<S extends object>(): Declaration<S>;
@@ -1,38 +1,47
1 import { primitive } from "../../safe";
1 import { primitive } from "../../safe";
2 import { ActivationType } from "../interfaces";
2 import { ActivationType } from "../interfaces";
3 import { Builder } from "../Annotations";
3
4
4 type ExtractService<K, S> = K extends keyof S ? S[K] : K;
5 type ExtractService<K, S> = K extends keyof S ? S[K] : K;
5
6
6 type ExtractDependency<D, S> = D extends { $dependency: infer K } ?
7 type ExtractDependency<D, S> = D extends { $dependency: infer K } ?
7 D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> :
8 D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> :
8 D extends { $type: new (...args: any[]) => infer I } ? I :
9 D extends { $type: new (...args: any[]) => infer I } ? I :
9 D extends { $factory: (...args: any[]) => infer R } ? R :
10 D extends { $factory: (...args: any[]) => infer R } ? R :
10 WalkDependencies<D, S>;
11 WalkDependencies<D, S>;
11
12
12 type WalkDependencies<D, S> = D extends primitive ? D :
13 type WalkDependencies<D, S> = D extends primitive ? D :
13 { [K in keyof D]: ExtractDependency<D[K], S> };
14 { [K in keyof D]: ExtractDependency<D[K], S> };
14
15
16 type ServiceModule<T, S extends object, M extends keyof any = "service"> = {
17 [m in M]: Builder<T, S>;
18 };
19
20 type PromiseOrValue<T> = T | PromiseLike<T>;
21
15 export interface TypeBuilder<T, S extends object> {
22 export interface TypeBuilder<T, S extends object> {
16 type<P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>(
23 type<P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>(
17 target: C, ...params: P): ConstructorBuilder<C, S>;
24 target: C, ...params: P): ConstructorBuilder<C, S>;
18 factory<P extends any[], F extends (...args: ExtractDependency<P, S>) => T>(
25 factory<P extends any[], F extends (...args: ExtractDependency<P, S>) => T>(
19 target: F, ...params: P): FactoryBuilder<F, S>;
26 target: F, ...params: P): FactoryBuilder<F, S>;
27 wire<M extends keyof any>(module: PromiseOrValue<ServiceModule<T, S, M>>, m: M): ServiceBuilder<T, S>;
28 wire(module: PromiseOrValue<ServiceModule<T, S>>): ServiceBuilder<T, S>;
20 }
29 }
21
30
22 export interface ServiceBuilder<T, S extends object> {
31 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;
32 override<K extends keyof S>(name: K, builder: S[K] | ((t: TypeBuilder<S[K], S>) => any)): this;
24 activate(activation: ActivationType): this;
33 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;
34 inject<M extends keyof T, P extends any[]>(member: T[M] extends (...params: ExtractDependency<P, S>) => any ? M : never, ...params: P): this;
26 }
35 }
27
36
28 export interface ConstructorBuilder<C extends new (...args: any[]) => any, S extends object> extends ServiceBuilder<InstanceType<C>, S> {
37 export interface ConstructorBuilder<C extends new (...args: any[]) => any, S extends object> extends ServiceBuilder<InstanceType<C>, S> {
29 $type: C;
38 $type: C;
30 }
39 }
31
40
32 export interface FactoryBuilder<F extends (...args: any[]) => any, S extends object> extends ServiceBuilder<ReturnType<F>, S> {
41 export interface FactoryBuilder<F extends (...args: any[]) => any, S extends object> extends ServiceBuilder<ReturnType<F>, S> {
33 $factory: F;
42 $factory: F;
34 }
43 }
35
44
36 export interface ConfigBuilder<S extends object, Y extends keyof S = keyof S> {
45 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>>;
46 register<K extends Y>(name: K, builder: S[K] | ((t: TypeBuilder<S[K], S>) => any)): ConfigBuilder<S, Exclude<Y, K>>;
38 }
47 }
@@ -1,30 +1,32
1 import { configure, dependency, Services, $type } from "./services";
1 import { configure, dependency, Services, $type } from "./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 import { declare } from "../di/Annotations";
6 import { ConfigBuilder, TypeBuilder } from "../di/fluent/interfaces";
5 import { ConfigBuilder, TypeBuilder } from "../di/fluent/interfaces";
7
6
8 export declare function build<T>(): TypeBuilder<T, Services>;
7 export declare function build<T>(): TypeBuilder<T, Services>;
9
8
10 export declare const config: ConfigBuilder<Services>;
9 export declare const config: ConfigBuilder<Services>;
11 config
10 config
12 //.register("bar", { $from: import("./Bar"), service: "service" })
11 .register("bar", s => s
13 // .register("box", { $from: import("./Box") })
12 .wire(import("./Bar"), "service")
13 .inject("setName", "heell")
14 )
15 .register("box", s => s.wire(import("./Box")))
14 .register("host", "example.com")
16 .register("host", "example.com")
15 // .registerType("bar2", Bar, [{ foo: dependency("foo"), host: "" }]);
17 // .registerType("bar2", Bar, [{ foo: dependency("foo"), host: "" }]);
16 .register("bar2", s => s.type(Bar,
18 .register("bar2", s => s.type(Bar,
17 {
19 {
18 foo: build().type(Foo)
20 foo: build().type(Foo)
19 .activate("context"),
21 .activate("context"),
20 nested: { lazy: dependency("foo", {lazy: true}) },
22 nested: { lazy: dependency("foo", {lazy: true}) },
21 host: dependency("host")
23 host: dependency("host")
22 },
24 },
23 "")
25 "")
24 .inject("setName", dependency("host"))
26 .inject("setName", dependency("host"))
25 )
27 )
26 .register("box", s => s
28 .register("box", s => s
27 .type(Box, dependency("bar"))
29 .type(Box, dependency("bar"))
28 .activate("context")
30 .activate("context")
29 );
31 );
30
32
@@ -1,25 +1,25
1 import { Foo } from "./Foo";
1 import { Foo } from "./Foo";
2 import { Bar } from "./Bar";
2 import { Bar } from "./Bar";
3 import { Box } from "./Box";
3 import { Box } from "./Box";
4 import { declare } from "../di/Annotations";
4 import { declare } from "../di/Annotations";
5
5
6 /**
6 /**
7 * Сервисы доступные внутри контейнера
7 * Сервисы доступные внутри контейнера
8 */
8 */
9 export interface Services {
9 export interface Services {
10 foo: Foo;
10 foo: Foo;
11
11
12 bar: Bar;
12 bar: Bar;
13
13
14 bar2: Bar;
14 bar2: Bar;
15
15
16 box: Box<Bar>;
16 box: Box<Bar>;
17
17
18 host: string;
18 host: string;
19
19
20 }
20 }
21
21
22 /**
22 /**
23 * Экспортируем вспомогательные функции для описания сервисов и кинфогурации
23 * Экспортируем вспомогательные функции для описания сервисов и кинфогурации
24 */
24 */
25 export const { define, dependency, configure, $type } = declare<Services>();
25 export const { define, dependency } = declare<Services>();
General Comments 0
You need to be logged in to leave comments. Login now