| @@ -0,0 +1,23 | |||
|
|
1 | import { Foo } from "./Foo"; | |
|
|
2 | import { Bar } from "./Bar"; | |
|
|
3 | import { Box } from "./Box"; | |
|
|
4 | import { declare } from "../di/Annotations"; | |
|
|
5 | ||
|
|
6 | /** | |
|
|
7 | * Сервисы доступные внутри контейнера | |
|
|
8 | */ | |
|
|
9 | export interface Services { | |
|
|
10 | foo: Foo; | |
|
|
11 | ||
|
|
12 | bar: Bar; | |
|
|
13 | ||
|
|
14 | box: Box<Bar>; | |
|
|
15 | ||
|
|
16 | host: string; | |
|
|
17 | ||
|
|
18 | } | |
|
|
19 | ||
|
|
20 | /** | |
|
|
21 | * Экспортируем вспомогательные функции для описания сервисов и кинфогурации | |
|
|
22 | */ | |
|
|
23 | export const { define, dependency, config } = declare<Services>(); | |
| @@ -1,21 +1,21 | |||
|
|
1 | import { Constructor } from "../interfaces"; | |
|
|
2 | 1 |
|
|
|
2 | import { TypeRegistration } from "./Configuration"; | |
|
|
3 | 3 | |
|
|
4 | 4 | export interface InjectOptions { |
|
|
5 | 5 | lazy?: boolean; |
|
|
6 | 6 | } |
|
|
7 | 7 | |
|
|
8 | interface Dependency<K extends keyof any> { | |
|
|
8 | export interface Dependency<K extends keyof any> { | |
|
|
9 | 9 | $dependency: K; |
|
|
10 | 10 | |
|
|
11 | 11 | lazy?: boolean; |
|
|
12 | 12 | } |
|
|
13 | 13 | |
|
|
14 | interface Lazy<K extends keyof any> extends Dependency<K> { | |
|
|
14 | export interface Lazy<K extends keyof any> extends Dependency<K> { | |
|
|
15 | 15 | lazy: true; |
|
|
16 | 16 | } |
|
|
17 | 17 | |
|
|
18 |
type Compatible<T1, T2> = T |
|
|
|
18 | type Compatible<T1, T2> = T2 extends T1 ? any : never; | |
|
|
19 | 19 | |
|
|
20 | 20 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; |
|
|
21 | 21 | |
| @@ -26,21 +26,10 type ExtractDependency<D, S> = D extends | |||
|
|
26 | 26 | type WalkDependencies<D, S> = D extends primitive ? D : |
|
|
27 | 27 | { [K in keyof D]: ExtractDependency<D[K], S> }; |
|
|
28 | 28 | |
|
|
29 | interface Services<S> { | |
|
|
30 | get<K extends keyof S>(name: K): Dependency<K>; | |
|
|
31 | ||
|
|
32 | lazy<K extends keyof S>(name: K): Lazy<K>; | |
|
|
33 | ||
|
|
34 | build<T extends object>(): Builder<T, S>; | |
|
|
35 | } | |
|
|
36 | ||
|
|
37 | export declare function services<S extends object>(): Services<S>; | |
|
|
38 | ||
|
|
39 | export declare function build<T = never, S = any>(): Builder<T, S>; | |
|
|
40 | ||
|
|
41 | 29 | export class Builder<T, S> { |
|
|
42 |
|
|
|
|
30 | declare<P extends any[]>(...args: P) { | |
|
|
43 | 31 | return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => { |
|
|
32 | return constructor as C & { service: Builder<T, S> }; | |
|
|
44 | 33 | }; |
|
|
45 | 34 | } |
|
|
46 | 35 | |
| @@ -59,17 +48,28 export class Builder<T, S> { | |||
|
|
59 | 48 | }; |
|
|
60 | 49 | } |
|
|
61 | 50 | |
|
|
62 | cast<T2 extends T>(): Builder<T2, S> { | |
|
|
63 | return this as Builder<T2, S>; | |
|
|
64 | } | |
|
|
65 | ||
|
|
66 | get<K extends keyof S>(name: K): Dependency<K> { | |
|
|
51 | getDescriptor(): TypeRegistration<T, any, S> { | |
|
|
67 | 52 | throw new Error(); |
|
|
68 | 53 | } |
|
|
69 | 54 | |
|
|
70 | lazy<K extends keyof S>(name: K): Lazy<K> { | |
|
|
71 | throw new Error(); | |
|
|
72 | } | |
|
|
55 | } | |
|
|
56 | ||
|
|
57 | interface Declaration<S> { | |
|
|
58 | define<T>(): Builder<T, S>; | |
|
|
59 | ||
|
|
60 | dependency<K extends keyof S>(name: K, opts: { lazy: true }): Lazy<K>; | |
|
|
61 | dependency<K extends keyof S>(name: K, opts?: any): Dependency<K>; | |
|
|
62 | ||
|
|
63 | config(): Config<S>; | |
|
|
64 | } | |
|
|
73 | 65 | |
|
|
66 | interface ServiceModule<T, S> { | |
|
|
67 | service: Builder<T, S>; | |
|
|
68 | } | |
|
|
74 | 69 | |
|
|
70 | interface Config<S> { | |
|
|
71 | register<K extends keyof S>(name: K, builder: Builder<S[K], S>): Config<Omit<S, K>>; | |
|
|
72 | register<K extends keyof S>(name: K, m: Promise<ServiceModule<S[K], S>>): Config<Omit<S, K>>; | |
|
|
75 | 73 | } |
|
|
74 | ||
|
|
75 | export declare function declare<S extends object>(): Declaration<S>; | |
| @@ -1,12 +1,12 | |||
|
|
1 | 1 | import { Foo } from "./Foo"; |
|
|
2 |
import { |
|
|
|
2 | import { define, dependency } from "./services"; | |
|
|
3 | 3 | |
|
|
4 |
const service = |
|
|
|
4 | export const service = define<Bar>(); | |
|
|
5 | 5 | |
|
|
6 |
@service. |
|
|
|
7 |
foo: |
|
|
|
6 | @service.declare({ | |
|
|
7 | foo: dependency("foo"), | |
|
|
8 | 8 | nested: { |
|
|
9 |
lazy: |
|
|
|
9 | lazy: dependency("foo", {lazy: true}) | |
|
|
10 | 10 | } |
|
|
11 | 11 | }) |
|
|
12 | 12 | export class Bar { |
| @@ -1,17 +1,12 | |||
|
|
1 | import { services } from "../di/Annotations"; | |
|
|
2 | 1 |
|
|
|
3 | import { Foo } from "./Foo"; | |
|
|
4 | ||
|
|
5 | // declare required dependencies | |
|
|
6 | const config = services<{ | |
|
|
7 | bar: Bar; | |
|
|
8 | foo: Foo; | |
|
|
9 | }>(); | |
|
|
2 | import { define, dependency } from "./services"; | |
|
|
10 | 3 | |
|
|
11 | 4 | // export service descriptor |
|
|
12 | export const service = config.build<Box<Bar>>(); | |
|
|
5 | // через service передается информация о типе зависимости | |
|
|
6 | // даже если это шаблон. | |
|
|
7 | export const service = define<Box<Bar>>(); | |
|
|
13 | 8 | |
|
|
14 |
@service. |
|
|
|
9 | @service.declare(dependency("bar")) | |
|
|
15 | 10 | export class Box<T> { |
|
|
16 | 11 | private _value: T | undefined; |
|
|
17 | 12 | |
| @@ -19,13 +14,13 export class Box<T> { | |||
|
|
19 | 14 | this._value = value; |
|
|
20 | 15 | } |
|
|
21 | 16 | |
|
|
22 |
@service.inject( |
|
|
|
23 |
setValue(value |
|
|
|
17 | @service.inject(dependency("bar")) | |
|
|
18 | setValue(value: T) { | |
|
|
24 | 19 | this._value = value; |
|
|
25 | 20 | return value; |
|
|
26 | 21 | } |
|
|
27 | 22 | |
|
|
28 |
setObj(value: |
|
|
|
23 | setObj(value: any) { | |
|
|
29 | 24 | |
|
|
30 | 25 | } |
|
|
31 | 26 | |
| @@ -1,27 +1,6 | |||
|
|
1 |
import { |
|
|
|
2 | import { Bar } from "./Bar"; | |
|
|
3 | import { Box } from "./Box"; | |
|
|
4 | import { Builder } from "../di/Annotations"; | |
|
|
5 | ||
|
|
6 | interface Services { | |
|
|
7 | foo: Foo; | |
|
|
8 | ||
|
|
9 | bar: Bar; | |
|
|
10 | ||
|
|
11 | box: Box<Foo>; | |
|
|
12 | ||
|
|
13 | host: string; | |
|
|
1 | import { config } from "./services"; | |
|
|
14 | 2 | |
|
|
15 | } | |
|
|
16 | ||
|
|
17 | const services = { | |
|
|
18 | build: <T>() => { | |
|
|
19 | return new Builder<T, Services>(); | |
|
|
20 | } | |
|
|
21 | }; | |
|
|
22 | ||
|
|
23 | namespace services { | |
|
|
24 | ||
|
|
25 | } | |
|
|
26 | ||
|
|
27 | export = services; | |
|
|
3 | config() | |
|
|
4 | .register("bar", import("./Bar")) | |
|
|
5 | .register("box", import("./Box")) | |
|
|
6 | .register("foo", import("./Foo"), "Foo"); | |
General Comments 0
You need to be logged in to leave comments.
Login now
