##// END OF EJS Templates
working on IoC configuration
cin -
r113:22cf333c0b34 ioc ts support
parent child
Show More
@@ -9,7 +9,7 export class ActivationError {
9
9
10 message: string;
10 message: string;
11
11
12 constructor(service: string, activationStack: ActivationContextInfo[], innerException) {
12 constructor(service: string, activationStack: ActivationContextInfo[], innerException: any) {
13 this.message = "Failed to activate the service";
13 this.message = "Failed to activate the service";
14 this.activationStack = activationStack;
14 this.activationStack = activationStack;
15 this.service = service;
15 this.service = service;
@@ -2,10 +2,10 import { Descriptor, isDescriptor } from
2 import { ActivationContext } from "./ActivationContext";
2 import { ActivationContext } from "./ActivationContext";
3 import { isPrimitive } from "../safe";
3 import { isPrimitive } from "../safe";
4
4
5 export class AggregateDescriptor implements Descriptor {
5 export class AggregateDescriptor<T> implements Descriptor<T> {
6 _value: object;
6 _value: T;
7
7
8 constructor(value: object) {
8 constructor(value: T) {
9 this._value = value;
9 this._value = value;
10 }
10 }
11
11
@@ -14,7 +14,7 export class AggregateDescriptor impleme
14 }
14 }
15
15
16 // TODO: make async
16 // TODO: make async
17 _parse(value, context: ActivationContext, path: string) {
17 _parse(value: T, context: ActivationContext, path: string) {
18 if (isPrimitive(value))
18 if (isPrimitive(value))
19 return value;
19 return value;
20
20
@@ -28,7 +28,7 import { ICancellation } from "../interf
28
28
29 const trace = TraceSource.get("@implab/core/di/Configuration");
29 const trace = TraceSource.get("@implab/core/di/Configuration");
30
30
31 async function mapAll(data: object | any[], map?: (v, k) => any): Promise<any> {
31 async function mapAll(data: any | any[], map?: (v: any, k: keyof any) => any): Promise<any> {
32 if (data instanceof Array) {
32 if (data instanceof Array) {
33 return Promise.all(map ? data.map(map) : data);
33 return Promise.all(map ? data.map(map) : data);
34 } else {
34 } else {
@@ -57,9 +57,9 export class Configuration {
57
57
58 _path: Array<_key>;
58 _path: Array<_key>;
59
59
60 _configName: string;
60 _configName: string | undefined;
61
61
62 _require: ModuleResolver;
62 _require: ModuleResolver | undefined;
63
63
64 constructor(container: Container) {
64 constructor(container: Container) {
65 argumentNotNull(container, "container");
65 argumentNotNull(container, "container");
@@ -78,7 +78,7 export class Configuration {
78
78
79 this._configName = moduleName;
79 this._configName = moduleName;
80
80
81 const r = await makeResolver(null, contextRequire);
81 const r = await makeResolver(undefined, contextRequire);
82
82
83 const config = await r(moduleName, ct);
83 const config = await r(moduleName, ct);
84
84
@@ -114,9 +114,9 export class Configuration {
114 this._container.register(services);
114 this._container.register(services);
115 }
115 }
116
116
117 _makeError(inner) {
117 _makeError(inner: any) {
118 const e = new ConfigError("Failed to load configuration", inner);
118 const e = new ConfigError("Failed to load configuration", inner);
119 e.configName = this._configName;
119 e.configName = this._configName || "<inline>";
120 e.path = this._makePath();
120 e.path = this._makePath();
121 return e;
121 return e;
122 }
122 }
@@ -144,11 +144,13 export class Configuration {
144
144
145 _loadModule(moduleName: string) {
145 _loadModule(moduleName: string) {
146 trace.debug("loadModule {0}", moduleName);
146 trace.debug("loadModule {0}", moduleName);
147 if (!this._require)
148 throw new Error("Module loader isn't specified");
147
149
148 return this._require(moduleName);
150 return this._require(moduleName);
149 }
151 }
150
152
151 async _visitRegistrations(data, name: _key) {
153 async _visitRegistrations(data: any, name: _key) {
152 this._enter(name);
154 this._enter(name);
153
155
154 if (data.constructor &&
156 if (data.constructor &&
@@ -168,8 +170,8 export class Configuration {
168 return services;
170 return services;
169 }
171 }
170
172
171 _enter(name: _key) {
173 _enter(name: keyof any) {
172 this._path.push(name);
174 this._path.push(name.toString());
173 trace.debug(">{0}", name);
175 trace.debug(">{0}", name);
174 }
176 }
175
177
@@ -178,7 +180,7 export class Configuration {
178 trace.debug("<{0}", name);
180 trace.debug("<{0}", name);
179 }
181 }
180
182
181 async _visit(data, name: string) {
183 async _visit<T extends object>(data: T, name: keyof T) {
182 if (isPrimitive(data) || isDescriptor(data))
184 if (isPrimitive(data) || isDescriptor(data))
183 return data;
185 return data;
184
186
@@ -233,7 +235,7 export class Configuration {
233 return v;
235 return v;
234 }
236 }
235
237
236 _makeServiceParams(data: ServiceRegistration) {
238 _makeServiceParams<T, P, S>(data: ServiceRegistration<T, P, S>) {
237 const opts: any = {
239 const opts: any = {
238 owner: this._container
240 owner: this._container
239 };
241 };
@@ -289,17 +291,17 export class Configuration {
289 return opts;
291 return opts;
290 }
292 }
291
293
292 async _visitValueRegistration(data: ValueRegistration, name: _key) {
294 async _visitValueRegistration<T>(data: ValueRegistration<T>, name: _key) {
293 this._enter(name);
295 this._enter(name);
294 const d = data.parse ? new AggregateDescriptor(data.$value) : new ValueDescriptor(data.$value);
296 const d = data.parse ? new AggregateDescriptor(data.$value) : new ValueDescriptor(data.$value);
295 this._leave();
297 this._leave();
296 return d;
298 return d;
297 }
299 }
298
300
299 async _visitDependencyRegistration(data: DependencyRegistration, name: _key) {
301 async _visitDependencyRegistration<S, K extends keyof S>(data: DependencyRegistration<S, K>, name: keyof S) {
300 argumentNotEmptyString(data && data.$dependency, "data.$dependency");
302 argumentNotEmptyString(data && data.$dependency, "data.$dependency");
301 this._enter(name);
303 this._enter(name);
302 const d = new ReferenceDescriptor({
304 const d = new ReferenceDescriptor<S, K>({
303 name: data.$dependency,
305 name: data.$dependency,
304 lazy: data.lazy,
306 lazy: data.lazy,
305 optional: data.optional,
307 optional: data.optional,
@@ -310,7 +312,7 export class Configuration {
310 return d;
312 return d;
311 }
313 }
312
314
313 async _visitTypeRegistration(data: TypeRegistration, name: _key) {
315 async _visitTypeRegistration<T, P, S>(data: TypeRegistration<T, P, S>, name: _key) {
314 argumentNotNull(data.$type, "data.$type");
316 argumentNotNull(data.$type, "data.$type");
315 this._enter(name);
317 this._enter(name);
316
318
@@ -331,7 +333,7 export class Configuration {
331 return d;
333 return d;
332 }
334 }
333
335
334 async _visitFactoryRegistration(data: FactoryRegistration, name: _key) {
336 async _visitFactoryRegistration<T, P, S>(data: FactoryRegistration<T, P, S>, name: _key) {
335 argumentOfType(data.$factory, Function, "data.$factory");
337 argumentOfType(data.$factory, Function, "data.$factory");
336 this._enter(name);
338 this._enter(name);
337
339
@@ -3,16 +3,16 import { ActivationContext } from "./Act
3 import { ServiceMap, Descriptor } from "./interfaces";
3 import { ServiceMap, Descriptor } from "./interfaces";
4 import { ActivationError } from "./ActivationError";
4 import { ActivationError } from "./ActivationError";
5
5
6 export interface ReferenceDescriptorParams {
6 export interface ReferenceDescriptorParams<S, K extends keyof S> {
7 name: string;
7 name: K;
8 lazy?: boolean;
8 lazy?: boolean;
9 optional?: boolean;
9 optional?: boolean;
10 default?;
10 default?: S[K];
11 services?: ServiceMap;
11 services?: ServiceMap;
12 }
12 }
13
13
14 export class ReferenceDescriptor implements Descriptor {
14 export class ReferenceDescriptor<S, K extends keyof S> implements Descriptor<S[K]> {
15 _name: string;
15 _name: K;
16
16
17 _lazy = false;
17 _lazy = false;
18
18
@@ -22,13 +22,14 export class ReferenceDescriptor impleme
22
22
23 _services: ServiceMap;
23 _services: ServiceMap;
24
24
25 constructor(opts: ReferenceDescriptorParams) {
25 constructor(opts: ReferenceDescriptorParams<S, K>) {
26 argumentNotEmptyString(opts && opts.name, "opts.name");
26 argumentNotEmptyString(opts && opts.name, "opts.name");
27 this._name = opts.name;
27 this._name = opts.name;
28 this._lazy = !!opts.lazy;
28 this._lazy = !!opts.lazy;
29 this._optional = !!opts.optional;
29 this._optional = !!opts.optional;
30 this._default = opts.default;
30 this._default = opts.default;
31 this._services = opts.services;
31
32 this._services = opts.services || {};
32 }
33 }
33
34
34 activate(context: ActivationContext, name: string) {
35 activate(context: ActivationContext, name: string) {
@@ -54,7 +55,7 export class ReferenceDescriptor impleme
54 return this._optional ? ct.resolve(this._name, this._default) : ct
55 return this._optional ? ct.resolve(this._name, this._default) : ct
55 .resolve(this._name);
56 .resolve(this._name);
56 } catch (error) {
57 } catch (error) {
57 throw new ActivationError(this._name, ct.getStack(), error);
58 throw new ActivationError(this._name.toString(), ct.getStack(), error);
58 }
59 }
59 };
60 };
60 } else {
61 } else {
@@ -88,7 +89,7 export class ReferenceDescriptor impleme
88 parts.push("} ");
89 parts.push("} ");
89 }
90 }
90
91
91 parts.push(this._name);
92 parts.push(this._name.toString());
92
93
93 if (!isNull(this._default)) {
94 if (!isNull(this._default)) {
94 parts.push(" = ");
95 parts.push(" = ");
@@ -1,9 +1,9
1 import { Descriptor } from "./interfaces";
1 import { Descriptor } from "./interfaces";
2
2
3 export class ValueDescriptor implements Descriptor {
3 export class ValueDescriptor<T> implements Descriptor<T> {
4 _value;
4 _value: T;
5
5
6 constructor(value) {
6 constructor(value: T) {
7 this._value = value;
7 this._value = value;
8 }
8 }
9
9
@@ -1,18 +1,18
1 import { isNull, isPrimitive } from "../safe";
1 import { isPrimitive } from "../safe";
2 import { ActivationContext } from "./ActivationContext";
2 import { ActivationContext } from "./ActivationContext";
3 import { Constructor, Factory } from "../interfaces";
3 import { Constructor, Factory } from "../interfaces";
4
4
5 export interface Descriptor {
5 export interface Descriptor<T = any> {
6 activate(context: ActivationContext, name?: string);
6 activate(context: ActivationContext, name?: string): T;
7 }
7 }
8
8
9 export function isDescriptor(x): x is Descriptor {
9 export function isDescriptor(x: any): x is Descriptor {
10 return (!isPrimitive(x)) &&
10 return (!isPrimitive(x)) &&
11 (x.activate instanceof Function);
11 (x.activate instanceof Function);
12 }
12 }
13
13
14 export interface ServiceMap {
14 export type ServiceMap<S = any> = {
15 [s: string]: Descriptor;
15 [k in keyof S]: Descriptor<S[k]>;
16 }
16 }
17
17
18 export enum ActivationType {
18 export enum ActivationType {
@@ -23,53 +23,53 export enum ActivationType {
23 Call
23 Call
24 }
24 }
25
25
26 export interface RegistrationWithServices {
26 export interface RegistrationWithServices<S> {
27 services?: object;
27 services?: ServiceMap<S>;
28 }
28 }
29
29
30 export interface ServiceRegistration extends RegistrationWithServices {
30 export interface ServiceRegistration<T, P, S> extends RegistrationWithServices<S> {
31
31
32 activation?: "singleton" | "container" | "hierarchy" | "context" | "call";
32 activation?: "singleton" | "container" | "hierarchy" | "context" | "call";
33
33
34 params?;
34 params?: P;
35
35
36 inject?: object | object[];
36 inject?: object | object[];
37
37
38 cleanup?: (instance) => void | string;
38 cleanup?: ((instance: T) => void) | string;
39 }
39 }
40
40
41 export interface TypeRegistration extends ServiceRegistration {
41 export interface TypeRegistration<T, P, S> extends ServiceRegistration<T, P, S> {
42 $type: string | Constructor;
42 $type: string | Constructor<T>;
43 }
43 }
44
44
45 export interface FactoryRegistration extends ServiceRegistration {
45 export interface FactoryRegistration<T, P, S> extends ServiceRegistration<T, P, S> {
46 $factory: string | Factory;
46 $factory: string | Factory<T>;
47 }
47 }
48
48
49 export interface ValueRegistration {
49 export interface ValueRegistration<T> {
50 $value;
50 $value: T;
51 parse?: boolean;
51 parse?: boolean;
52 }
52 }
53
53
54 export interface DependencyRegistration extends RegistrationWithServices {
54 export interface DependencyRegistration<S, K extends keyof S> extends RegistrationWithServices<S> {
55 $dependency: string;
55 $dependency: K;
56 lazy?: boolean;
56 lazy?: boolean;
57 optional?: boolean;
57 optional?: boolean;
58 default?;
58 default?: S[K];
59 }
59 }
60
60
61 export function isTypeRegistration(x): x is TypeRegistration {
61 export function isTypeRegistration(x: any): x is TypeRegistration<any, any, any> {
62 return (!isPrimitive(x)) && ("$type" in x);
62 return (!isPrimitive(x)) && ("$type" in x);
63 }
63 }
64
64
65 export function isFactoryRegistration(x): x is FactoryRegistration {
65 export function isFactoryRegistration(x: any): x is FactoryRegistration<any, any, any> {
66 return (!isPrimitive(x)) && ("$factory" in x);
66 return (!isPrimitive(x)) && ("$factory" in x);
67 }
67 }
68
68
69 export function isValueRegistration(x): x is ValueRegistration {
69 export function isValueRegistration(x: any): x is ValueRegistration<any> {
70 return (!isPrimitive(x)) && ("$value" in x);
70 return (!isPrimitive(x)) && ("$value" in x);
71 }
71 }
72
72
73 export function isDependencyRegistration(x): x is DependencyRegistration {
73 export function isDependencyRegistration(x: any): x is DependencyRegistration<any, string | number | symbol> {
74 return (!isPrimitive(x)) && ("$dependency" in x);
74 return (!isPrimitive(x)) && ("$dependency" in x);
75 }
75 }
General Comments 0
You need to be logged in to leave comments. Login now