| @@ -71,7 +71,6 function(declare, safe, when, QueryResul | |||
|
|
71 | 71 | }); |
|
|
72 | 72 | mapped.total = total; |
|
|
73 | 73 | var results = new QueryResults(mapped); |
|
|
74 | console.log(results); | |
|
|
75 | 74 | return results; |
|
|
76 | 75 | }); |
|
|
77 | 76 | }, |
| @@ -2,8 +2,10 import { Cancellation } from "../Cancell | |||
|
|
2 | 2 | import { IAsyncComponent, ICancellation, ICancellable, IDestroyable } from "../interfaces"; |
|
|
3 | 3 | import { destroy } from "../safe"; |
|
|
4 | 4 | |
|
|
5 | const noop = () => void (0); | |
|
|
6 | ||
|
|
5 | 7 | export class AsyncComponent implements IAsyncComponent, ICancellable { |
|
|
6 |
_cancel: ((e: any) => void) |
|
|
|
8 | _cancel: ((e: any) => void) = noop; | |
|
|
7 | 9 | |
|
|
8 | 10 | _completion: Promise<void> = Promise.resolve(); |
|
|
9 | 11 | |
| @@ -26,7 +28,7 export class AsyncComponent implements I | |||
|
|
26 | 28 | // after the operation is complete we need to cleanup the |
|
|
27 | 29 | // resources |
|
|
28 | 30 | destroy(h); |
|
|
29 |
this._cancel = |
|
|
|
31 | this._cancel = noop; | |
|
|
30 | 32 | } |
|
|
31 | 33 | }; |
|
|
32 | 34 | |
| @@ -34,7 +36,6 export class AsyncComponent implements I | |||
|
|
34 | 36 | } |
|
|
35 | 37 | |
|
|
36 | 38 | cancel(reason: any) { |
|
|
37 |
|
|
|
|
38 | this._cancel(reason); | |
|
|
39 | this._cancel(reason); | |
|
|
39 | 40 | } |
|
|
40 | 41 | } |
| @@ -1,6 +1,6 | |||
|
|
1 | 1 | import { TraceSource } from "../log/TraceSource"; |
|
|
2 | 2 | import { argumentNotEmptyString } from "../safe"; |
|
|
3 | import { Descriptor, ContainerServiceMap, ContainerKeys, TypeOfService } from "./interfaces"; | |
|
|
3 | import { Descriptor, ContainerServiceMap, ContainerKeys, TypeOfService, ILifetime } from "./interfaces"; | |
|
|
4 | 4 | import { Container } from "./Container"; |
|
|
5 | 5 | import { MapOf } from "../interfaces"; |
|
|
6 | 6 | |
| @@ -13,6 +13,8 export interface ActivationContextInfo { | |||
|
|
13 | 13 | |
|
|
14 | 14 | } |
|
|
15 | 15 | |
|
|
16 | let nextId = 1; | |
|
|
17 | ||
|
|
16 | 18 | export class ActivationContext<S extends object> { |
|
|
17 | 19 | _cache: MapOf<any>; |
|
|
18 | 20 | |
| @@ -73,18 +75,23 export class ActivationContext<S extends | |||
|
|
73 | 75 | this._services[name] = service as any; |
|
|
74 | 76 | } |
|
|
75 | 77 | |
|
|
76 | has(id: string) { | |
|
|
77 | return id in this._cache; | |
|
|
78 | createLifetime(): ILifetime { | |
|
|
79 | const id = nextId++; | |
|
|
80 | const me = this; | |
|
|
81 | return { | |
|
|
82 | initialize() { | |
|
|
83 | }, | |
|
|
84 | has() { | |
|
|
85 | return id in me._cache; | |
|
|
86 | }, | |
|
|
87 | get() { | |
|
|
88 | return me._cache[id]; | |
|
|
89 | }, | |
|
|
90 | store(item: any) { | |
|
|
91 | me._cache[id] = item; | |
|
|
92 | } | |
|
|
93 | }; | |
|
|
78 | 94 | } |
|
|
79 | ||
|
|
80 | get<T>(id: string) { | |
|
|
81 | return this._cache[id]; | |
|
|
82 | } | |
|
|
83 | ||
|
|
84 | store(id: string, value: any) { | |
|
|
85 | return (this._cache[id] = value); | |
|
|
86 | } | |
|
|
87 | ||
|
|
88 | 95 | activate<T>(d: Descriptor<S, T>, name: string) { |
|
|
89 | 96 | if (trace.isLogEnabled()) |
|
|
90 | 97 | trace.log(`enter ${name} ${d}`); |
| @@ -3,7 +3,7 import { | |||
|
|
3 | 3 | ActivationType, |
|
|
4 | 4 | ContainerKeys, |
|
|
5 | 5 | TypeOfService, |
|
|
6 |
ILifetime |
|
|
|
6 | ILifetime | |
|
|
7 | 7 | } from "./interfaces"; |
|
|
8 | 8 | |
|
|
9 | 9 | import { argumentNotEmptyString, isPrimitive, isPromise, delegate, argumentOfType, argumentNotNull, get, primitive } from "../safe"; |
| @@ -281,9 +281,11 export class Configuration<S extends obj | |||
|
|
281 | 281 | trace.debug("<{0}", name); |
|
|
282 | 282 | } |
|
|
283 | 283 | |
|
|
284 |
|
|
|
|
285 |
if (isPrimitive(data) |
|
|
|
286 | return data; | |
|
|
284 | _visit(data: any, name: string): Promise<any> { | |
|
|
285 | if (isPrimitive(data)) | |
|
|
286 | return Promise.resolve(new ValueDescriptor(data)); | |
|
|
287 | if (isDescriptor(data)) | |
|
|
288 | return Promise.resolve(data); | |
|
|
287 | 289 | |
|
|
288 | 290 | if (isDependencyRegistration<S>(data)) { |
|
|
289 | 291 | return this._visitDependencyRegistration(data, name); |
| @@ -398,9 +400,11 export class Configuration<S extends obj | |||
|
|
398 | 400 | opts.type = data.$type; |
|
|
399 | 401 | } else { |
|
|
400 | 402 | const [moduleName, typeName] = data.$type.split(":", 2); |
|
|
401 |
|
|
|
|
402 | if (!(t instanceof Function)) | |
|
|
403 | throw Error("$type (" + data.$type + ") is not a constructable"); | |
|
|
403 | opts.type = this._resolveType(moduleName, typeName).then(t => { | |
|
|
404 | if (!(t instanceof Function)) | |
|
|
405 | throw Error("$type (" + data.$type + ") is not a constructable"); | |
|
|
406 | return t; | |
|
|
407 | }); | |
|
|
404 | 408 | } |
|
|
405 | 409 | |
|
|
406 | 410 | const d = new TypeServiceDescriptor<S, any, any[]>( |
| @@ -427,20 +431,20 export class Configuration<S extends obj | |||
|
|
427 | 431 | return d; |
|
|
428 | 432 | } |
|
|
429 | 433 | |
|
|
430 |
_getLifetimeManager(activation: ActivationType, typeId: string | undefined): ILifetime |
|
|
|
434 | _getLifetimeManager(activation: ActivationType, typeId: string | undefined): ILifetime { | |
|
|
431 | 435 | switch (activation) { |
|
|
432 | 436 | case "container": |
|
|
433 | return this._container.getLifetimeManager(); | |
|
|
437 | return LifetimeManager.containerLifetime(this._container); | |
|
|
434 | 438 | case "hierarchy": |
|
|
435 | return LifetimeManager.hierarchyLifetime; | |
|
|
439 | return LifetimeManager.hierarchyLifetime(); | |
|
|
436 | 440 | case "context": |
|
|
437 | return LifetimeManager.contextLifetime; | |
|
|
441 | return LifetimeManager.contextLifetime(); | |
|
|
438 | 442 | case "singleton": |
|
|
439 | 443 | if (typeId === undefined) |
|
|
440 | 444 | throw Error("The singleton activation requires a typeId"); |
|
|
441 | 445 | return LifetimeManager.singletonLifetime(typeId); |
|
|
442 | 446 | default: |
|
|
443 | return LifetimeManager.empty; | |
|
|
447 | return LifetimeManager.empty(); | |
|
|
444 | 448 | } |
|
|
445 | 449 | } |
|
|
446 | 450 | } |
| @@ -38,7 +38,7 export class LazyReferenceDescriptor<S e | |||
|
|
38 | 38 | |
|
|
39 | 39 | const saved = context.clone(); |
|
|
40 | 40 | |
|
|
41 | return (cfg?: PartialServiceMap<S>) => { | |
|
|
41 | return (cfg?: PartialServiceMap<S>): any => { | |
|
|
42 | 42 | // защищаем контекст на случай исключения в процессе |
|
|
43 | 43 | // активации |
|
|
44 | 44 | const ct = cfg ? saved.clone() : saved; |
| @@ -2,6 +2,7 import { IDestroyable, MapOf } from "../ | |||
|
|
2 | 2 | import { argumentNotNull, isDestroyable } from "../safe"; |
|
|
3 | 3 | import { ILifetimeManager, ILifetime } from "./interfaces"; |
|
|
4 | 4 | import { ActivationContext } from "./ActivationContext"; |
|
|
5 | import { Container } from "./Container"; | |
|
|
5 | 6 | |
|
|
6 | 7 | function safeCall(item: () => void) { |
|
|
7 | 8 | try { |
| @@ -16,7 +17,7 const emptyLifetime: ILifetime = { | |||
|
|
16 | 17 | return false; |
|
|
17 | 18 | }, |
|
|
18 | 19 | |
|
|
19 | enter() { | |
|
|
20 | initialize() { | |
|
|
20 | 21 | |
|
|
21 | 22 | }, |
|
|
22 | 23 | |
| @@ -30,6 +31,21 const emptyLifetime: ILifetime = { | |||
|
|
30 | 31 | |
|
|
31 | 32 | }; |
|
|
32 | 33 | |
|
|
34 | const unknownLifetime: ILifetime = { | |
|
|
35 | has() { | |
|
|
36 | throw new Error("The lifetime is unknown"); | |
|
|
37 | }, | |
|
|
38 | initialize() { | |
|
|
39 | throw new Error("Can't call initialize on the unknown lifetime object"); | |
|
|
40 | }, | |
|
|
41 | get() { | |
|
|
42 | throw new Error("The lifetime object isn't initialized"); | |
|
|
43 | }, | |
|
|
44 | store() { | |
|
|
45 | throw new Error("Can't store a value in the unknown lifetime object"); | |
|
|
46 | } | |
|
|
47 | } | |
|
|
48 | ||
|
|
33 | 49 | let nextId = 0; |
|
|
34 | 50 | |
|
|
35 | 51 | export class LifetimeManager implements IDestroyable, ILifetimeManager { |
| @@ -39,7 +55,7 export class LifetimeManager implements | |||
|
|
39 | 55 | |
|
|
40 | 56 | private _pending: MapOf<boolean> = {}; |
|
|
41 | 57 | |
|
|
42 |
|
|
|
|
58 | create(): ILifetime { | |
|
|
43 | 59 | const self = this; |
|
|
44 | 60 | const id = ++nextId; |
|
|
45 | 61 | return { |
| @@ -54,7 +70,7 export class LifetimeManager implements | |||
|
|
54 | 70 | return t; |
|
|
55 | 71 | }, |
|
|
56 | 72 | |
|
|
57 |
|
|
|
|
73 | initialize() { | |
|
|
58 | 74 | if (self._pending[id]) |
|
|
59 | 75 | throw Error(`Cyclic reference detected: the item with the key ${id} is already activating.`); |
|
|
60 | 76 | self._pending[id] = true; |
| @@ -89,43 +105,71 export class LifetimeManager implements | |||
|
|
89 | 105 | } |
|
|
90 | 106 | } |
|
|
91 | 107 | |
|
|
92 |
static |
|
|
|
93 | initialize(): ILifetime { | |
|
|
94 | return emptyLifetime; | |
|
|
95 | } | |
|
|
96 | }; | |
|
|
108 | static empty(): ILifetime { | |
|
|
109 | return emptyLifetime; | |
|
|
110 | } | |
|
|
111 | ||
|
|
112 | static hierarchyLifetime(): ILifetime { | |
|
|
113 | let _lifetime = unknownLifetime; | |
|
|
114 | return { | |
|
|
115 | initialize(context: ActivationContext<any>) { | |
|
|
116 | if (_lifetime !== unknownLifetime) | |
|
|
117 | throw new Error("Cyclic reference activation detected"); | |
|
|
97 | 118 | |
|
|
98 | static readonly hierarchyLifetime: ILifetimeManager = { | |
|
|
99 | initialize(context: ActivationContext<any>): ILifetime { | |
|
|
100 | return context.getContainer().getLifetimeManager().initialize(context); | |
|
|
101 | } | |
|
|
102 | }; | |
|
|
119 | _lifetime = context.getContainer().getLifetimeManager().create(context); | |
|
|
120 | }, | |
|
|
121 | get() { | |
|
|
122 | return _lifetime.get(); | |
|
|
123 | }, | |
|
|
124 | has() { | |
|
|
125 | return _lifetime.has(); | |
|
|
126 | }, | |
|
|
127 | store(item: any, cleanup?: (item: any) => void) { | |
|
|
128 | return _lifetime.store(item, cleanup); | |
|
|
129 | } | |
|
|
130 | }; | |
|
|
131 | } | |
|
|
103 | 132 | |
|
|
104 |
static |
|
|
|
105 | initialize(context: ActivationContext<any>): ILifetime { | |
|
|
106 | const id = String(++nextId); | |
|
|
107 | return { | |
|
|
108 | enter() { | |
|
|
109 | if (context.visit(id)) | |
|
|
110 | throw new Error("Cyclic reference detected"); | |
|
|
111 |
|
|
|
|
112 |
|
|
|
|
113 |
|
|
|
|
114 |
|
|
|
|
115 |
|
|
|
|
116 |
|
|
|
|
117 |
|
|
|
|
118 |
|
|
|
|
119 |
|
|
|
|
120 |
|
|
|
|
121 |
|
|
|
|
122 |
|
|
|
|
123 | }; | |
|
|
133 | static contextLifetime(): ILifetime { | |
|
|
134 | let _lifetime = unknownLifetime; | |
|
|
135 | return { | |
|
|
136 | initialize(context: ActivationContext<any>) { | |
|
|
137 | if (_lifetime !== unknownLifetime) | |
|
|
138 | throw new Error("Cyclic reference detected"); | |
|
|
139 | _lifetime = context.createLifetime(); | |
|
|
140 | }, | |
|
|
141 | get() { | |
|
|
142 | return _lifetime.get(); | |
|
|
143 | }, | |
|
|
144 | has() { | |
|
|
145 | return _lifetime.has(); | |
|
|
146 | }, | |
|
|
147 | store(item: any) { | |
|
|
148 | _lifetime.store(item); | |
|
|
149 | } | |
|
|
150 | }; | |
|
|
151 | } | |
|
|
124 | 152 | |
|
|
125 |
static singletonLifetime(typeId: string): ILifetime |
|
|
|
153 | static singletonLifetime(typeId: string): ILifetime { | |
|
|
154 | return emptyLifetime; | |
|
|
155 | } | |
|
|
156 | ||
|
|
157 | static containerLifetime(container: Container<any>) { | |
|
|
158 | let _lifetime = unknownLifetime; | |
|
|
126 | 159 | return { |
|
|
127 | initialize() { | |
|
|
128 |
|
|
|
|
160 | initialize(context: ActivationContext<any>) { | |
|
|
161 | if (_lifetime !== unknownLifetime) | |
|
|
162 | throw new Error("Cyclic reference detected"); | |
|
|
163 | _lifetime = container.getLifetimeManager().create(context); | |
|
|
164 | }, | |
|
|
165 | get() { | |
|
|
166 | return _lifetime.get(); | |
|
|
167 | }, | |
|
|
168 | has() { | |
|
|
169 | return _lifetime.has(); | |
|
|
170 | }, | |
|
|
171 | store(item: any) { | |
|
|
172 | _lifetime.store(item); | |
|
|
129 | 173 | } |
|
|
130 | 174 | }; |
|
|
131 | 175 | } |
| @@ -3,9 +3,26 import { ActivationContext } from "./Act | |||
|
|
3 | 3 | import { Descriptor, PartialServiceMap, TypeOfService, ContainerKeys } from "./interfaces"; |
|
|
4 | 4 | |
|
|
5 | 5 | export interface ReferenceDescriptorParams<S extends object, K extends ContainerKeys<S>> { |
|
|
6 | /** | |
|
|
7 | * The name of the descriptor | |
|
|
8 | */ | |
|
|
6 | 9 | name: K; |
|
|
10 | ||
|
|
11 | /** | |
|
|
12 | * The flag that indicates that the referenced service isn't required to exist. | |
|
|
13 | * If the reference is optional and the referenced service doesn't exist, | |
|
|
14 | * the undefined or a default value will be returned. | |
|
|
15 | */ | |
|
|
7 | 16 | optional?: boolean; |
|
|
17 | ||
|
|
18 | /** | |
|
|
19 | * a default value for the reference when the referenced service doesn't exist. | |
|
|
20 | */ | |
|
|
8 | 21 | default?: TypeOfService<S, K>; |
|
|
22 | ||
|
|
23 | /** | |
|
|
24 | * The service overrides | |
|
|
25 | */ | |
|
|
9 | 26 | services?: PartialServiceMap<S>; |
|
|
10 | 27 | } |
|
|
11 | 28 | |
| @@ -29,7 +46,10 export class ReferenceDescriptor<S exten | |||
|
|
29 | 46 | this._services = (opts.services || {}) as PartialServiceMap<S>; |
|
|
30 | 47 | } |
|
|
31 | 48 | |
|
|
32 | activate(context: ActivationContext<S>) { | |
|
|
49 | /** This method activates the referenced service if one exists | |
|
|
50 | * @param context activation context which is used during current activation | |
|
|
51 | */ | |
|
|
52 | activate(context: ActivationContext<S>): any { | |
|
|
33 | 53 | // добавляем сервисы |
|
|
34 | 54 | if (this._services) { |
|
|
35 | 55 | each(this._services, (v, k) => context.register(k, v)); |
| @@ -59,7 +59,7 export type InjectionSpec<T> = { | |||
|
|
59 | 59 | }; |
|
|
60 | 60 | |
|
|
61 | 61 | export interface ServiceDescriptorParams<S extends object, T, P extends any[]> { |
|
|
62 |
lifetime?: ILifetime |
|
|
|
62 | lifetime?: ILifetime; | |
|
|
63 | 63 | |
|
|
64 | 64 | params?: P; |
|
|
65 | 65 | |
| @@ -79,14 +79,14 export class ServiceDescriptor<S extends | |||
|
|
79 | 79 | |
|
|
80 | 80 | _cleanup: ((item: T) => void) | undefined; |
|
|
81 | 81 | |
|
|
82 |
_lifetime |
|
|
|
82 | _lifetime = LifetimeManager.empty(); | |
|
|
83 | 83 | |
|
|
84 | 84 | _objectLifetime: ILifetime | undefined; |
|
|
85 | 85 | |
|
|
86 | 86 | constructor(opts: ServiceDescriptorParams<S, T, P>) { |
|
|
87 | 87 | |
|
|
88 | 88 | if (opts.lifetime) |
|
|
89 |
this._lifetime |
|
|
|
89 | this._lifetime = opts.lifetime; | |
|
|
90 | 90 | |
|
|
91 | 91 | if (!isNull(opts.params)) |
|
|
92 | 92 | this._params = opts.params; |
| @@ -105,15 +105,12 export class ServiceDescriptor<S extends | |||
|
|
105 | 105 | } |
|
|
106 | 106 | |
|
|
107 | 107 | activate(context: ActivationContext<S>) { |
|
|
108 | if (!this._objectLifetime) | |
|
|
109 | this._objectLifetime = this._lifetimeManager.initialize(context); | |
|
|
110 | ||
|
|
111 | const lifetime = this._objectLifetime; | |
|
|
108 | const lifetime = this._lifetime; | |
|
|
112 | 109 | |
|
|
113 | 110 | if (lifetime.has()) { |
|
|
114 | 111 | return lifetime.get(); |
|
|
115 | 112 | } else { |
|
|
116 |
lifetime. |
|
|
|
113 | lifetime.initialize(context); | |
|
|
117 | 114 | const instance = this._create(context); |
|
|
118 | 115 | lifetime.store(instance, this._cleanup); |
|
|
119 | 116 | return instance; |
| @@ -1,5 +1,4 | |||
|
|
1 |
import { Resolver |
|
|
|
2 | import { AnnotationBuilder } from "../Annotations"; | |
|
|
1 | import { Resolver, LazyDependencyOptions, DependencyOptions } from "./interfaces"; | |
|
|
3 | 2 | import { Container } from "../Container"; |
|
|
4 | 3 | import { Descriptor, ILifetime, ContainerKeys } from "../interfaces"; |
|
|
5 | 4 | import { ActivationContext } from "../ActivationContext"; |
| @@ -12,9 +11,6 export class DescriptorBuilder<T, S exte | |||
|
|
12 | 11 | this._container = container; |
|
|
13 | 12 | this._cb = cb; |
|
|
14 | 13 | } |
|
|
15 | service(service: AnnotationBuilder<T, S> | ServiceModule<T, S>) { | |
|
|
16 | ||
|
|
17 | } | |
|
|
18 | 14 | |
|
|
19 | 15 | factory(f: (resolve: Resolver<S>, activate: (lifetime: ILifetime, factory: () => any, cleanup?: (item: any) => void) => any) => T): void { |
|
|
20 | 16 | this._cb({ |
| @@ -34,7 +30,7 export class DescriptorBuilder<T, S exte | |||
|
|
34 | 30 | if (lifetime.has()) { |
|
|
35 | 31 | return lifetime.get(); |
|
|
36 | 32 | } else { |
|
|
37 |
lifetime. |
|
|
|
33 | lifetime.initialize(context); | |
|
|
38 | 34 | const instance = factory(); |
|
|
39 | 35 | lifetime.store(instance, cleanup); |
|
|
40 | 36 | return instance; |
| @@ -26,13 +26,13 export type ServiceModule<T, S extends o | |||
|
|
26 | 26 | [m in M]: AnnotationBuilder<T, S>; |
|
|
27 | 27 | }; |
|
|
28 | 28 | |
|
|
29 |
export type InferReferenceType<S extends object, K extends |
|
|
|
29 | export type InferReferenceType<S extends object, K extends ContainerKeys<S>, O> = O extends { default: infer X } ? (TypeOfService<S, K> | X) : | |
|
|
30 | 30 | O extends { optional: true } ? (TypeOfService<S, K> | undefined) : |
|
|
31 | 31 | TypeOfService<S, K>; |
|
|
32 | 32 | |
|
|
33 | 33 | export interface Resolver<S extends object> { |
|
|
34 |
<K extends |
|
|
|
35 |
<K extends |
|
|
|
34 | <K extends ContainerKeys<S>, O extends LazyDependencyOptions>(this: void, name: K, opts: O): () => InferReferenceType<S, K, O>; | |
|
|
35 | <K extends ContainerKeys<S>, O extends DependencyOptions>(this: void, name: K, opts?: O): InferReferenceType<S, K, O>; | |
|
|
36 | 36 | } |
|
|
37 | 37 | |
|
|
38 | 38 | export interface DescriptorBuilder<T, S extends object> { |
| @@ -38,7 +38,7 export type ContainerRegistered<S extend | |||
|
|
38 | 38 | export type ActivationType = "singleton" | "container" | "hierarchy" | "context" | "call"; |
|
|
39 | 39 | |
|
|
40 | 40 | export interface ILifetimeManager { |
|
|
41 |
|
|
|
|
41 | create(context: ActivationContext<any>): ILifetime; | |
|
|
42 | 42 | } |
|
|
43 | 43 | |
|
|
44 | 44 | /** |
| @@ -51,7 +51,7 export interface ILifetime { | |||
|
|
51 | 51 | |
|
|
52 | 52 | get(): any; |
|
|
53 | 53 | |
|
|
54 | enter(): void; | |
|
|
54 | initialize(context: ActivationContext<any>): void; | |
|
|
55 | 55 | |
|
|
56 | 56 | store(item: any, cleanup?: (item: any) => void): void; |
|
|
57 | 57 | } |
| @@ -1,6 +1,5 | |||
|
|
1 | 1 | import { isPrimitive } from "../safe"; |
|
|
2 | 2 | import { Descriptor } from "./interfaces"; |
|
|
3 | import { AnnotationBuilder } from "./Annotations"; | |
|
|
4 | 3 | import { Configuration } from "./fluent/Configuration"; |
|
|
5 | 4 | |
|
|
6 | 5 | export function isDescriptor(x: any): x is Descriptor { |
| @@ -8,16 +7,6 export function isDescriptor(x: any): x | |||
|
|
8 | 7 | (x.activate instanceof Function); |
|
|
9 | 8 | } |
|
|
10 | 9 | |
|
|
11 |
export function |
|
|
|
12 | return { | |
|
|
13 | annotate<T>() { | |
|
|
14 | return new AnnotationBuilder<T, S>(); | |
|
|
15 | }, | |
|
|
16 | configure(): Configuration<S> { | |
|
|
17 | throw new Error(); | |
|
|
18 | }, | |
|
|
19 | dependency() { | |
|
|
20 | throw new Error(); | |
|
|
21 | } | |
|
|
22 | }; | |
|
|
10 | export function configure<S extends object>() { | |
|
|
11 | return new Configuration<S>(); | |
|
|
23 | 12 | } |
| @@ -129,8 +129,7 export function get(member: string, cont | |||
|
|
129 | 129 | * @param {Function} cb функция, вызываемая для каждого элемента |
|
|
130 | 130 | * @param {Object} thisArg значение, которое будет передано в качестве |
|
|
131 | 131 | * <c>this</c> в <c>cb</c>. |
|
|
132 | * @returns Результат вызова функции <c>cb</c>, либо <c>undefined</c> | |
|
|
133 | * если достигнут конец массива. | |
|
|
132 | * @returns {void} | |
|
|
134 | 133 | */ |
|
|
135 | 134 | export function each<T>(obj: T, cb: <X extends keyof T>(v: NonNullable<T[X]>, k: X) => void): void; |
|
|
136 | 135 | export function each<T>(array: T[], cb: (v: T, i: number) => void): void; |
| @@ -138,18 +137,14 export function each(obj: any, cb: any, | |||
|
|
138 | 137 | export function each(obj: any, cb: any, thisArg?: any) { |
|
|
139 | 138 | argumentNotNull(cb, "cb"); |
|
|
140 | 139 | if (obj instanceof Array) { |
|
|
140 | let v: any; | |
|
|
141 | 141 | for (let i = 0; i < obj.length; i++) { |
|
|
142 |
|
|
|
|
143 |
if ( |
|
|
|
144 | return x; | |
|
|
142 | v = obj[i]; | |
|
|
143 | if (v !== undefined) | |
|
|
144 | cb.call(thisArg, v, i); | |
|
|
145 | 145 | } |
|
|
146 | 146 | } else { |
|
|
147 | const _keys = Object.keys(obj); | |
|
|
148 | for (const k of _keys) { | |
|
|
149 | const x = cb.call(thisArg, obj[k], k); | |
|
|
150 | if (x !== undefined) | |
|
|
151 | return x; | |
|
|
152 | } | |
|
|
147 | Object.keys(obj).forEach(k => obj[k] !== undefined && cb.call(thisArg, obj[k], k)); | |
|
|
153 | 148 | } |
|
|
154 | 149 | } |
|
|
155 | 150 | |
| @@ -478,7 +473,7 export function firstWhere<T>( | |||
|
|
478 | 473 | } |
|
|
479 | 474 | |
|
|
480 | 475 | export function isDestroyable(d: any): d is IDestroyable { |
|
|
481 | if (d && "destroy" in d && typeof(destroy) === "function") | |
|
|
476 | if (d && "destroy" in d && typeof (destroy) === "function") | |
|
|
482 | 477 | return true; |
|
|
483 | 478 | return false; |
|
|
484 | 479 | } |
| @@ -1,4 +1,4 | |||
|
|
1 |
import { isPrimitive, isNull |
|
|
|
1 | import { isPrimitive, isNull, isKeyof, get } from "../safe"; | |
|
|
2 | 2 | import { MapOf } from "../interfaces"; |
|
|
3 | 3 | |
|
|
4 | 4 | type SubstFn = (name: string, format?: string) => string; |
| @@ -1,7 +1,6 | |||
|
|
1 | 1 | import { Foo } from "./Foo"; |
|
|
2 | import { annotate, dependency } from "./services"; | |
|
|
3 | 2 | |
|
|
4 | export const service = annotate<Bar>(); | |
|
|
3 | /* export const service = annotate<Bar>(); | |
|
|
5 | 4 | |
|
|
6 | 5 | @service.wire({ |
|
|
7 | 6 | foo: dependency("foo"), |
| @@ -9,22 +8,27 export const service = annotate<Bar>(); | |||
|
|
9 | 8 | lazy: dependency("foo", { lazy: true }) |
|
|
10 | 9 | }, |
|
|
11 | 10 | host: dependency("host") |
|
|
12 |
|
|
|
|
11 | }, "") */ | |
|
|
13 | 12 | export class Bar { |
|
|
14 | 13 | barName = "Twister"; |
|
|
15 | 14 | |
|
|
16 | 15 | _v: Foo | undefined; |
|
|
17 | 16 | |
|
|
18 |
constructor( |
|
|
|
19 |
|
|
|
|
20 | nested?: { | |
|
|
21 | lazy: () => Foo | |
|
|
17 | constructor( | |
|
|
18 | _opts: { | |
|
|
19 | foo?: Foo; | |
|
|
20 | nested?: { | |
|
|
21 | lazy: () => Foo | |
|
|
22 | }, | |
|
|
23 | host: string | |
|
|
22 | 24 | }, |
|
|
23 |
|
|
|
|
24 | }, s: string) { | |
|
|
25 | s: string | |
|
|
26 | ) { | |
|
|
25 | 27 | |
|
|
26 | 28 | if (_opts && _opts.foo) |
|
|
27 | 29 | this._v = _opts.foo; |
|
|
30 | if (s) | |
|
|
31 | this.barName = s; | |
|
|
28 | 32 | } |
|
|
29 | 33 | |
|
|
30 | 34 | setName(name: string) { |
| @@ -1,12 +1,11 | |||
|
|
1 | 1 | import { Bar } from "./Bar"; |
|
|
2 | import { annotate, dependency } from "./services"; | |
|
|
3 | 2 | |
|
|
4 | 3 | // export service descriptor |
|
|
5 | 4 | // через service передается информация о типе зависимости |
|
|
6 | 5 | // даже если это шаблон. |
|
|
7 | export const service = annotate<Box<Bar>>(); | |
|
|
6 | // export const service = annotate<Box<Bar>>(); | |
|
|
8 | 7 | |
|
|
9 | @service.wire() | |
|
|
8 | // @service.wire() | |
|
|
10 | 9 | export class Box<T> { |
|
|
11 | 10 | private _value: T | undefined; |
|
|
12 | 11 | |
| @@ -14,7 +13,7 export class Box<T> { | |||
|
|
14 | 13 | this._value = value; |
|
|
15 | 14 | } |
|
|
16 | 15 | |
|
|
17 | @service.inject(dependency("bar")) | |
|
|
16 | // @service.inject(dependency("bar")) | |
|
|
18 | 17 | setValue(value: T) { |
|
|
19 | 18 | this._value = value; |
|
|
20 | 19 | return value; |
| @@ -1,10 +1,13 | |||
|
|
1 |
import { c |
|
|
|
1 | import { Services } from "./services"; | |
|
|
2 | import { configure } from "../di/traits"; | |
|
|
3 | import { LifetimeManager } from "../di/LifetimeManager"; | |
|
|
2 | 4 | |
|
|
3 | export const config = configure() | |
|
|
5 | export const config = configure<Services>() | |
|
|
4 | 6 | .register("host", s => s.value("example.com")) |
|
|
5 | 7 | .register("bar2", bar2 => Promise.all([import("./Foo"), import("./Bar")]) |
|
|
6 | 8 | .then(([{ Foo }, { Bar }]) => { |
|
|
7 |
const lifetime |
|
|
|
9 | const lifetime = LifetimeManager.hierarchyLifetime(); | |
|
|
10 | ||
|
|
8 | 11 |
|
|
|
9 | 12 | const bar = new Bar({ |
|
|
10 | 13 | foo: activate(lifetime, () => new Foo()), |
| @@ -1,7 +1,6 | |||
|
|
1 | 1 | import { Foo } from "./Foo"; |
|
|
2 | 2 | import { Bar } from "./Bar"; |
|
|
3 | 3 | import { Box } from "./Box"; |
|
|
4 | import { declare } from "../di/traits"; | |
|
|
5 | 4 | |
|
|
6 | 5 | /** |
|
|
7 | 6 | * Сервисы доступные внутри контейнера |
| @@ -18,8 +17,3 export interface Services { | |||
|
|
18 | 17 | host: string; |
|
|
19 | 18 | |
|
|
20 | 19 | } |
|
|
21 | ||
|
|
22 | /** | |
|
|
23 | * Экспортируем вспомогательные функции для описания сервисов и кинфогурации | |
|
|
24 | */ | |
|
|
25 | export const { dependency, annotate, configure } = declare<Services>(); | |
|
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now
