| @@ -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 | import { primitive } from "../safe"; | |
|
|
2 | import { TypeRegistration } from "./Configuration"; | |||
| 3 |
|
3 | |||
| 4 | export interface InjectOptions { |
|
4 | export interface InjectOptions { | |
| 5 | lazy?: boolean; |
|
5 | lazy?: boolean; | |
| 6 | } |
|
6 | } | |
| 7 |
|
7 | |||
| 8 | interface Dependency<K extends keyof any> { |
|
8 | export interface Dependency<K extends keyof any> { | |
| 9 | $dependency: K; |
|
9 | $dependency: K; | |
| 10 |
|
10 | |||
| 11 | lazy?: boolean; |
|
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 | lazy: true; |
|
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 | type ExtractService<K, S> = K extends keyof S ? S[K] : K; |
|
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 | type WalkDependencies<D, S> = D extends primitive ? D : |
|
26 | type WalkDependencies<D, S> = D extends primitive ? D : | |
| 27 | { [K in keyof D]: ExtractDependency<D[K], S> }; |
|
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 | export class Builder<T, S> { |
|
29 | export class Builder<T, S> { | |
| 42 |
|
|
30 | declare<P extends any[]>(...args: P) { | |
| 43 | return <C extends new (...args: ExtractDependency<P, S>) => T>(constructor: C) => { |
|
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> { |
|
51 | getDescriptor(): TypeRegistration<T, any, S> { | |
| 63 | return this as Builder<T2, S>; |
|
|||
| 64 | } |
|
|||
| 65 |
|
||||
| 66 | get<K extends keyof S>(name: K): Dependency<K> { |
|
|||
| 67 | throw new Error(); |
|
52 | throw new Error(); | |
| 68 | } |
|
53 | } | |
| 69 |
|
54 | |||
| 70 | lazy<K extends keyof S>(name: K): Lazy<K> { |
|
55 | } | |
| 71 | throw new Error(); |
|
56 | ||
| 72 | } |
|
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 | import { Foo } from "./Foo"; |
|
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. |
|
6 | @service.declare({ | |
| 7 |
foo: |
|
7 | foo: dependency("foo"), | |
| 8 | nested: { |
|
8 | nested: { | |
| 9 |
lazy: |
|
9 | lazy: dependency("foo", {lazy: true}) | |
| 10 | } |
|
10 | } | |
| 11 | }) |
|
11 | }) | |
| 12 | export class Bar { |
|
12 | export class Bar { | |
| @@ -1,17 +1,12 | |||||
| 1 | import { services } from "../di/Annotations"; |
|
|||
| 2 |
|
|
1 | import { Bar } from "./Bar"; | |
| 3 | import { Foo } from "./Foo"; |
|
2 | import { define, dependency } from "./services"; | |
| 4 |
|
||||
| 5 | // declare required dependencies |
|
|||
| 6 | const config = services<{ |
|
|||
| 7 | bar: Bar; |
|
|||
| 8 | foo: Foo; |
|
|||
| 9 | }>(); |
|
|||
| 10 |
|
3 | |||
| 11 | // export service descriptor |
|
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 | export class Box<T> { |
|
10 | export class Box<T> { | |
| 16 | private _value: T | undefined; |
|
11 | private _value: T | undefined; | |
| 17 |
|
12 | |||
| @@ -19,13 +14,13 export class Box<T> { | |||||
| 19 | this._value = value; |
|
14 | this._value = value; | |
| 20 | } |
|
15 | } | |
| 21 |
|
16 | |||
| 22 |
@service.inject( |
|
17 | @service.inject(dependency("bar")) | |
| 23 |
setValue(value |
|
18 | setValue(value: T) { | |
| 24 | this._value = value; |
|
19 | this._value = value; | |
| 25 | return value; |
|
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 { |
|
1 | import { config } from "./services"; | |
| 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; |
|
|||
| 14 |
|
2 | |||
| 15 | } |
|
3 | config() | |
| 16 |
|
4 | .register("bar", import("./Bar")) | ||
| 17 | const services = { |
|
5 | .register("box", import("./Box")) | |
| 18 | build: <T>() => { |
|
6 | .register("foo", import("./Foo"), "Foo"); | |
| 19 | return new Builder<T, Services>(); |
|
|||
| 20 | } |
|
|||
| 21 | }; |
|
|||
| 22 |
|
||||
| 23 | namespace services { |
|
|||
| 24 |
|
||||
| 25 | } |
|
|||
| 26 |
|
||||
| 27 | export = services; |
|
|||
General Comments 0
You need to be logged in to leave comments.
Login now
