| @@ -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 |
|
|
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 |
|
25 | export const { define, dependency } = declare<Services>(); | |
General Comments 0
You need to be logged in to leave comments.
Login now
