| @@ -1,24 +1,8 | |||
|
|
1 |
import { |
|
|
|
2 | import { TypeRegistration, DependencyRegistration, LazyDependencyRegistration, Registration, StrictTypeRegistration } from "./Configuration"; | |
|
|
3 | ||
|
|
4 | export interface InjectOptions { | |
|
|
5 | lazy?: boolean; | |
|
|
6 | } | |
|
|
7 | ||
|
|
8 | type Compatible<T1, T2> = T2 extends T1 ? any : never; | |
|
|
9 | ||
|
|
10 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; | |
|
|
1 | import { TypeRegistration } from "./Configuration"; | |
|
|
2 | import { ExtractDependency } from "./fluent/interfaces"; | |
|
|
11 | 3 | |
|
|
12 | type ExtractDependency<D, S> = D extends { $dependency: infer K } ? | |
|
|
13 | D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> : | |
|
|
14 | D extends { $type: new (...args: any[]) => infer I } ? I : | |
|
|
15 | WalkDependencies<D, S>; | |
|
|
16 | ||
|
|
17 | type WalkDependencies<D, S> = D extends primitive ? D : | |
|
|
18 | { [K in keyof D]: ExtractDependency<D[K], S> }; | |
|
|
19 | ||
|
|
20 | export class Builder<T, S extends object> { | |
|
|
21 | declare<P extends any[]>(...args: P) { | |
|
|
4 | export class AnnotaionBuilder<T, S extends object> { | |
|
|
5 | wire<P extends any[]>(...args: P) { | |
|
|
22 | 6 | return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => { |
|
|
23 | 7 | |
|
|
24 | 8 | }; |
| @@ -28,7 +12,7 export class Builder<T, S extends object | |||
|
|
28 | 12 | return <X extends { [m in M]: (...args: any) => any }, M extends keyof (T | X)>( |
|
|
29 | 13 | target: X, |
|
|
30 | 14 | memberName: M, |
|
|
31 |
descriptor: TypedPropertyDescriptor< |
|
|
|
15 | descriptor: TypedPropertyDescriptor< T[M] extends ((...args: ExtractDependency<P, S>) => any) ? any : never > | |
|
|
32 | 16 | ) => { |
|
|
33 | 17 | |
|
|
34 | 18 | }; |
| @@ -39,24 +23,3 export class Builder<T, S extends object | |||
|
|
39 | 23 | } |
|
|
40 | 24 | |
|
|
41 | 25 | } |
|
|
42 | ||
|
|
43 | export interface DependencyOptions<T> { | |
|
|
44 | optional?: boolean; | |
|
|
45 | default?: T; | |
|
|
46 | } | |
|
|
47 | ||
|
|
48 | export interface LazyDependencyOptions<T> extends DependencyOptions<T> { | |
|
|
49 | lazy: true; | |
|
|
50 | } | |
|
|
51 | ||
|
|
52 | interface Declaration<S extends object> { | |
|
|
53 | define<T>(): Builder<T, S>; | |
|
|
54 | ||
|
|
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>; | |
|
|
57 | ||
|
|
58 | $type<T, P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>(target: C, ...params: P): StrictTypeRegistration<C, S>; | |
|
|
59 | } | |
|
|
60 | ||
|
|
61 | ||
|
|
62 | export declare function declare<S extends object>(): Declaration<S>; | |
| @@ -1,47 +1,68 | |||
|
|
1 | 1 | import { primitive } from "../../safe"; |
|
|
2 | 2 | import { ActivationType } from "../interfaces"; |
|
|
3 | import { Builder } from "../Annotations"; | |
|
|
3 | import { AnnotaionBuilder } from "../Annotations"; | |
|
|
4 | import { LazyDependencyRegistration, DependencyRegistration } from "../Configuration"; | |
|
|
5 | import { PromiseOrValue } from "../../interfaces"; | |
|
|
4 | 6 | |
|
|
5 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; | |
|
|
7 | export interface DependencyOptions<T> { | |
|
|
8 | optional?: boolean; | |
|
|
9 | default?: T; | |
|
|
10 | } | |
|
|
6 | 11 | |
|
|
7 | type ExtractDependency<D, S> = D extends { $dependency: infer K } ? | |
|
|
12 | export interface LazyDependencyOptions<T> extends DependencyOptions<T> { | |
|
|
13 | lazy: true; | |
|
|
14 | } | |
|
|
15 | ||
|
|
16 | export type ExtractService<K, S> = K extends keyof S ? S[K] : K; | |
|
|
17 | ||
|
|
18 | export type ExtractDependency<D, S> = D extends { $dependency: infer K } ? | |
|
|
8 | 19 | D extends { lazy: true } ? () => ExtractService<K, S> : ExtractService<K, S> : |
|
|
9 | 20 | D extends { $type: new (...args: any[]) => infer I } ? I : |
|
|
10 | 21 | D extends { $factory: (...args: any[]) => infer R } ? R : |
|
|
11 | 22 | WalkDependencies<D, S>; |
|
|
12 | 23 | |
|
|
13 | type WalkDependencies<D, S> = D extends primitive ? D : | |
|
|
24 | export type WalkDependencies<D, S> = D extends primitive ? D : | |
|
|
14 | 25 | { [K in keyof D]: ExtractDependency<D[K], S> }; |
|
|
15 | 26 | |
|
|
16 | type ServiceModule<T, S extends object, M extends keyof any = "service"> = { | |
|
|
17 | [m in M]: Builder<T, S>; | |
|
|
27 | export type ServiceModule<T, S extends object, M extends keyof any = "service"> = { | |
|
|
28 | [m in M]: AnnotaionBuilder<T, S>; | |
|
|
18 | 29 | }; |
|
|
19 | 30 | |
|
|
20 | type PromiseOrValue<T> = T | PromiseLike<T>; | |
|
|
21 | ||
|
|
22 | export interface TypeBuilder<T, S extends object> { | |
|
|
31 | export interface ServiceBuilder<T, S extends object> { | |
|
|
23 | 32 | type<P extends any[], C extends new (...args: ExtractDependency<P, S>) => T>( |
|
|
24 | 33 | target: C, ...params: P): ConstructorBuilder<C, S>; |
|
|
25 | 34 | factory<P extends any[], F extends (...args: ExtractDependency<P, S>) => T>( |
|
|
26 | 35 | target: F, ...params: P): FactoryBuilder<F, S>; |
|
|
27 |
wire<M extends keyof any>(module: PromiseOrValue<ServiceModule<T, S, M>>, m: M): |
|
|
|
28 |
wire(module: PromiseOrValue<ServiceModule<T, S>>): |
|
|
|
36 | wired<M extends keyof any>(module: PromiseOrValue<ServiceModule<T, S, M>>, m: M): RegistrationBuilder<T, S>; | |
|
|
37 | wired(module: PromiseOrValue<ServiceModule<T, S>>): RegistrationBuilder<T, S>; | |
|
|
29 | 38 | } |
|
|
30 | 39 | |
|
|
31 |
export interface |
|
|
|
32 |
override<K extends keyof S>(name: K, builder: S[K] | ((t: |
|
|
|
40 | export interface RegistrationBuilder<T, S extends object> { | |
|
|
41 | override<K extends keyof S>(name: K, builder: S[K] | ((t: ServiceBuilder<S[K], S>) => any)): this; | |
|
|
33 | 42 | activate(activation: ActivationType): this; |
|
|
34 | 43 | inject<M extends keyof T, P extends any[]>(member: T[M] extends (...params: ExtractDependency<P, S>) => any ? M : never, ...params: P): this; |
|
|
35 | 44 | } |
|
|
36 | 45 | |
|
|
37 |
export interface ConstructorBuilder<C extends new (...args: any[]) => any, S extends object> extends |
|
|
|
46 | export interface ConstructorBuilder<C extends new (...args: any[]) => any, S extends object> extends RegistrationBuilder<InstanceType<C>, S> { | |
|
|
38 | 47 | $type: C; |
|
|
39 | 48 | } |
|
|
40 | 49 | |
|
|
41 |
export interface FactoryBuilder<F extends (...args: any[]) => any, S extends object> extends |
|
|
|
50 | export interface FactoryBuilder<F extends (...args: any[]) => any, S extends object> extends RegistrationBuilder<ReturnType<F>, S> { | |
|
|
42 | 51 | $factory: F; |
|
|
43 | 52 | } |
|
|
44 | 53 | |
|
|
45 | 54 | export interface ConfigBuilder<S extends object, Y extends keyof S = keyof S> { |
|
|
46 |
register<K extends Y>(name: K, builder: S[K] | ((t: |
|
|
|
55 | register<K extends Y>(name: K, builder: S[K] | ((t: ServiceBuilder<S[K], S>) => any)): ConfigBuilder<S, Exclude<Y, K>>; | |
|
|
47 | 56 | } |
|
|
57 | ||
|
|
58 | interface ServicesDeclaration<S extends object> { | |
|
|
59 | build<T>(this: void): ServiceBuilder<T, S>; | |
|
|
60 | annotate<T>(this: void): AnnotaionBuilder<T, S>; | |
|
|
61 | ||
|
|
62 | dependency<K extends keyof S>(this: void, name: K, opts: LazyDependencyOptions<S[K]>): LazyDependencyRegistration<S, K>; | |
|
|
63 | dependency<K extends keyof S>(this: void, name: K, opts?: DependencyOptions<S[K]>): DependencyRegistration<S, K>; | |
|
|
64 | ||
|
|
65 | configure(): ConfigBuilder<S>; | |
|
|
66 | } | |
|
|
67 | ||
|
|
68 | export declare function declare<S extends object>(): ServicesDeclaration<S>; | |
| @@ -3,6 +3,8 export interface Constructor<T = {}> { | |||
|
|
3 | 3 | prototype: T; |
|
|
4 | 4 | } |
|
|
5 | 5 | |
|
|
6 | export type PromiseOrValue<T> = T | PromiseLike<T>; | |
|
|
7 | ||
|
|
6 | 8 | export type Factory<T = {}> = (...args: any[]) => T; |
|
|
7 | 9 | |
|
|
8 | 10 | export type Predicate<T = any> = (x: T) => boolean; |
| @@ -1,9 +1,9 | |||
|
|
1 | 1 | import { Foo } from "./Foo"; |
|
|
2 |
import { |
|
|
|
2 | import { annotate, dependency } from "./services"; | |
|
|
3 | 3 | |
|
|
4 |
export const service = |
|
|
|
4 | export const service = annotate<Bar>(); | |
|
|
5 | 5 | |
|
|
6 |
@service. |
|
|
|
6 | @service.wire({ | |
|
|
7 | 7 | foo: dependency("foo"), |
|
|
8 | 8 | nested: { |
|
|
9 | 9 | lazy: dependency("foo", { lazy: true }) |
| @@ -11,7 +11,7 export const service = define<Bar>(); | |||
|
|
11 | 11 | host: dependency("host") |
|
|
12 | 12 | }, "") |
|
|
13 | 13 | export class Bar { |
|
|
14 |
barName = " |
|
|
|
14 | barName = "Twister"; | |
|
|
15 | 15 | |
|
|
16 | 16 | _v: Foo | undefined; |
|
|
17 | 17 | |
| @@ -1,16 +1,16 | |||
|
|
1 | 1 | import { Bar } from "./Bar"; |
|
|
2 |
import { |
|
|
|
2 | import { annotate, dependency } from "./services"; | |
|
|
3 | 3 | |
|
|
4 | 4 | // export service descriptor |
|
|
5 | 5 | // через service передается информация о типе зависимости |
|
|
6 | 6 | // даже если это шаблон. |
|
|
7 |
export const service = |
|
|
|
7 | export const service = annotate<Box<Bar>>(); | |
|
|
8 | 8 | |
|
|
9 | @service.declare(dependency("bar")) | |
|
|
9 | @service.wire() | |
|
|
10 | 10 | export class Box<T> { |
|
|
11 | 11 | private _value: T | undefined; |
|
|
12 | 12 | |
|
|
13 | constructor(value: T) { | |
|
|
13 | constructor(value?: T) { | |
|
|
14 | 14 | this._value = value; |
|
|
15 | 15 | } |
|
|
16 | 16 | |
| @@ -20,10 +20,6 export class Box<T> { | |||
|
|
20 | 20 | return value; |
|
|
21 | 21 | } |
|
|
22 | 22 | |
|
|
23 | setObj(value: any) { | |
|
|
24 | ||
|
|
25 | } | |
|
|
26 | ||
|
|
27 | 23 | getValue() { |
|
|
28 | 24 | if (this._value === undefined) |
|
|
29 | 25 | throw new Error("Trying to get a value from the empty box"); |
| @@ -1,18 +1,14 | |||
|
|
1 |
import { configure, dependency, |
|
|
|
1 | import { configure, dependency, build } from "./services"; | |
|
|
2 | 2 | import { Foo } from "./Foo"; |
|
|
3 | 3 | import { Bar } from "./Bar"; |
|
|
4 | 4 | import { Box } from "./Box"; |
|
|
5 | import { ConfigBuilder, TypeBuilder } from "../di/fluent/interfaces"; | |
|
|
6 | 5 | |
|
|
7 | export declare function build<T>(): TypeBuilder<T, Services>; | |
|
|
8 | ||
|
|
9 | export declare const config: ConfigBuilder<Services>; | |
|
|
10 | config | |
|
|
6 | export const config = configure() | |
|
|
11 | 7 | .register("bar", s => s |
|
|
12 | .wire(import("./Bar"), "service") | |
|
|
8 | .wired(import("./Bar"), "service") | |
|
|
13 | 9 | .inject("setName", "heell") |
|
|
14 | 10 | ) |
|
|
15 | .register("box", s => s.wire(import("./Box"))) | |
|
|
11 | .register("box", s => s.wired(import("./Box"))) | |
|
|
16 | 12 | .register("host", "example.com") |
|
|
17 | 13 | // .registerType("bar2", Bar, [{ foo: dependency("foo"), host: "" }]); |
|
|
18 | 14 | .register("bar2", s => s.type(Bar, |
| @@ -1,7 +1,7 | |||
|
|
1 | 1 | import { Foo } from "./Foo"; |
|
|
2 | 2 | import { Bar } from "./Bar"; |
|
|
3 | 3 | import { Box } from "./Box"; |
|
|
4 |
import { declare } from "../di/ |
|
|
|
4 | import { declare } from "../di/fluent/interfaces"; | |
|
|
5 | 5 | |
|
|
6 | 6 | /** |
|
|
7 | 7 | * Сервисы доступные внутри контейнера |
| @@ -22,4 +22,4 export interface Services { | |||
|
|
22 | 22 | /** |
|
|
23 | 23 | * Экспортируем вспомогательные функции для описания сервисов и кинфогурации |
|
|
24 | 24 | */ |
|
|
25 |
export const { de |
|
|
|
25 | export const { dependency, build, annotate, configure } = declare<Services>(); | |
General Comments 0
You need to be logged in to leave comments.
Login now
