##// END OF EJS Templates
code comments
cin -
r2:154d88dba49c default
parent child
Show More
@@ -1,67 +1,94
1 import { DescriptorBuilder } from "./DescriptorBuilder";
1 import { DescriptorBuilder } from "./DescriptorBuilder";
2 import { ConfigurableKeys, ContainerServices, ConfigurableServices, RegistrationBuildersMap, RequiredKeys } from "./interfaces";
2 import { ConfigurableKeys, ContainerServices, ConfigurableServices, RegistrationBuildersMap, ExtractRequired } from "./interfaces";
3 import { ServiceContainer } from "./interfaces";
3 import { ServiceContainer } from "./interfaces";
4 import { argumentNotNull, each, isKey } from "./traits";
4 import { argumentNotNull, each, isKey } from "./traits";
5
5
6 export class FluentConfiguration<S extends object, Y extends ConfigurableKeys<S> = ConfigurableKeys<S>> {
6 export class FluentConfiguration<S extends object, Y extends ConfigurableKeys<S> = ConfigurableKeys<S>> {
7
7
8 _builders: Partial<RegistrationBuildersMap<S>> = {};
8 private _builders: Partial<RegistrationBuildersMap<S>> = {};
9
9
10 /** Adds a declaration of the services to the current config.
11 *
12 * @template D The map of the services
13 * @returns self
14 */
10 declare<D extends Partial<Pick<S, keyof D & keyof S>>>(): FluentConfiguration<S & D, Y | ConfigurableKeys<D>> {
15 declare<D extends Partial<Pick<S, keyof D & keyof S>>>(): FluentConfiguration<S & D, Y | ConfigurableKeys<D>> {
11 return this as FluentConfiguration<S & D, Y | ConfigurableKeys<D>>;
16 return this as FluentConfiguration<S & D, Y | ConfigurableKeys<D>>;
12 }
17 }
13
18
19 /** Adds compile-time information about the already provided services
20 *
21 * @template P The map of the provided services
22 * @returns self
23 */
14 provided<P extends Pick<S, keyof P & keyof S>>(): FluentConfiguration<S & P, Exclude<Y, keyof P>> {
24 provided<P extends Pick<S, keyof P & keyof S>>(): FluentConfiguration<S & P, Exclude<Y, keyof P>> {
15 return this as FluentConfiguration<S & P, Exclude<Y, keyof P>>;
25 return this as FluentConfiguration<S & P, Exclude<Y, keyof P>>;
16 }
26 }
17
27
28 /** Register the service.
29 *
30 * @param name The name of the service
31 * @param builder The service builder
32 * @returns self
33 */
18 register<K extends Y>(name: K, builder: RegistrationBuildersMap<S>[K]): FluentConfiguration<S, Exclude<Y, K>>;
34 register<K extends Y>(name: K, builder: RegistrationBuildersMap<S>[K]): FluentConfiguration<S, Exclude<Y, K>>;
35 /** Registers the collection of services
36 * @param config The collection of services to register.
37 * @returns self
38 */
19 register<K extends Y>(config: RegistrationBuildersMap<S, K>): FluentConfiguration<S, Exclude<Y, K>>;
39 register<K extends Y>(config: RegistrationBuildersMap<S, K>): FluentConfiguration<S, Exclude<Y, K>>;
20 register<K extends Y>(nameOrConfig: K | RegistrationBuildersMap<S, K>, builder?: RegistrationBuildersMap<S>[K]) {
40 register<K extends Y>(nameOrConfig: K | RegistrationBuildersMap<S, K>, builder?: RegistrationBuildersMap<S>[K]) {
21 if (isKey(nameOrConfig)) {
41 if (isKey(nameOrConfig)) {
22 argumentNotNull(builder, "builder");
42 argumentNotNull(builder, "builder");
23 this._builders[nameOrConfig] = builder;
43 this._builders[nameOrConfig] = builder;
24 } else {
44 } else {
25 each(nameOrConfig, (v, k) => this.register(k, v));
45 each(nameOrConfig, (v, k) => this.register(k, v));
26 }
46 }
27
47
28 return this as FluentConfiguration<S, Exclude<Y, K>>;
48 return this as FluentConfiguration<S, Exclude<Y, K>>;
29 }
49 }
30
50
31 done(missing: RequiredKeys<S, Y> extends never ? void : RequiredKeys<S, Y>) {
51 /**
32 if (missing !== undefined)
52 * This method is used to enable a compile time check of the configuration.
33 throw new Error("The configuration isn't complete");
53 * If there are not configured services in the configuration the compiler
54 * will trigger the error.
55 *
56 * @param missing Empty object literal should always be specified.
57 * @returns self
58 */
59 // eslint-disable-next-line @typescript-eslint/no-unused-vars
60 done<M extends ExtractRequired<S,Y>>(missing: M) {
34 return this;
61 return this;
35 }
62 }
36
63
37
64
38 apply<A extends Partial<S>>(target: ServiceContainer<A>) {
65 apply<A extends Partial<S>>(target: ServiceContainer<A>) {
39
66
40 let pending = 1;
67 let pending = 1;
41
68
42 const _t2 = target as ServiceContainer<S>;
69 const _t2 = target as ServiceContainer<S>;
43
70
44 const reject = (ex: unknown) => { throw ex; };
71 const reject = (ex: unknown) => { throw ex; };
45
72
46 const complete = () => !--pending;
73 const complete = () => !--pending;
47
74
48 each(this._builders, (v, k) => {
75 each(this._builders, (v, k) => {
49 pending++;
76 pending++;
50 const d = new DescriptorBuilder<ContainerServices<S>, NonNullable<ConfigurableServices<S>[typeof k]>>(_t2,
77 const d = new DescriptorBuilder<ContainerServices<S>, NonNullable<ConfigurableServices<S>[typeof k]>>(_t2,
51 result => {
78 result => {
52 _t2.register(k, result);
79 _t2.register(k, result);
53 complete();
80 complete();
54 },
81 },
55 reject
82 reject
56 );
83 );
57
84
58
85
59 v(d);
86 v(d);
60 });
87 });
61 if (!complete())
88 if (!complete())
62 throw new Error("The configuration didn't complete.");
89 throw new Error("The configuration didn't complete.");
63
90
64 return _t2 as ServiceContainer<A & S>;
91 return _t2 as ServiceContainer<A & S>;
65 }
92 }
66
93
67 }
94 }
@@ -1,121 +1,121
1 import { ActivationContext } from "./ActivationContext";
1 import { ActivationContext } from "./ActivationContext";
2
2
3 export type primitive = number | string | null | undefined | symbol;
3 export type primitive = number | string | null | undefined | symbol;
4
4
5 export interface IDestroyable {
5 export interface IDestroyable {
6 destroy(): void;
6 destroy(): void;
7 }
7 }
8
8
9 /**
9 /**
10 * @template S ΠšΠ°Ρ€Ρ‚Π° доступных зависимостСй
10 * @template S ΠšΠ°Ρ€Ρ‚Π° доступных зависимостСй
11 */
11 */
12 export interface Resolver<S extends object> {
12 export interface Resolver<S extends object> {
13 /**
13 /**
14 * Ѐункция для Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ зависимостСй, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ созданиС Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²,
14 * Ѐункция для Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ зависимостСй, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ созданиС Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ²,
15 * ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΡƒΡŽ Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΡŽ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для сСрвисов
15 * ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΡƒΡŽ Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΡŽ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для сСрвисов
16 * @template K ΠšΠ»ΡŽΡ‡ сСрвиса ΠΈΠ· {@link S}
16 * @template K ΠšΠ»ΡŽΡ‡ сСрвиса ΠΈΠ· {@link S}
17 * @template O Π’ΠΈΠΏ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° {@link opts} ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для вывСдСния Ρ‚ΠΈΠΏΠ°
17 * @template O Π’ΠΈΠΏ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° {@link opts} ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для вывСдСния Ρ‚ΠΈΠΏΠ°
18 * Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния.
18 * Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния.
19 * @param name ΠšΠ»ΡŽΡ‡ сСрвиса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½.
19 * @param name ΠšΠ»ΡŽΡ‡ сСрвиса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½.
20 * @param {boolean=} opts.lazy ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ трСбуСтся отлоТСнная активация,
20 * @param {boolean=} opts.lazy ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ трСбуСтся отлоТСнная активация,
21 * Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для получСния зависимости. Если Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½,
21 * Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для получСния зависимости. Если Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½,
22 * Ρ‚ΠΎ считаСтся `false`.
22 * Ρ‚ΠΎ считаСтся `false`.
23 * @param {any=} opts.default Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Ссли Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ
23 * @param {any=} opts.default Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Ссли Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ
24 * сСрвис Π½Π΅ зарСгистрирован
24 * сСрвис Π½Π΅ зарСгистрирован
25 * @returns Π›ΠΈΠ±ΠΎ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для получСния зависимости, Π»ΠΈΠ±ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ зависимости
25 * @returns Π›ΠΈΠ±ΠΎ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ для получСния зависимости, Π»ΠΈΠ±ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ зависимости
26 * @throws Error Если Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° ΠΈ Π½Π΅ прСдоставлСно Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
26 * @throws Error Если Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π° ΠΈ Π½Π΅ прСдоставлСно Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ-ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ
27 */
27 */
28 <K extends keyof S, O extends { lazy: true; default?: unknown }>(name: K, opts?: O): () => (O extends { default: infer T } ? T : never) | NonNullable<S[K]>;
28 <K extends keyof S, O extends { lazy: true; default?: unknown }>(name: K, opts?: O): () => (O extends { default: infer T } ? T : never) | NonNullable<S[K]>;
29 <K extends keyof S, O extends { lazy?: false; default?: unknown }>(name: K, opts?: O): (O extends { default: infer T } ? T : never) | NonNullable<S[K]>;
29 <K extends keyof S, O extends { lazy?: false; default?: unknown }>(name: K, opts?: O): (O extends { default: infer T } ? T : never) | NonNullable<S[K]>;
30 }
30 }
31
31
32 export interface DescriptorBuilder<S extends object, T> {
32 export interface DescriptorBuilder<S extends object, T> {
33
33
34 /**
34 /**
35 *
35 *
36 * @param f
36 * @param f
37 */
37 */
38 factory(f: (resolve: Resolver<S>) => T): void;
38 factory(f: (resolve: Resolver<S>) => T): void;
39
39
40 override<K extends ConfigurableKeys<S>>(name: K, builder: RegistrationBuilder<S, NonNullable<S[K]>>): this;
40 override<K extends ConfigurableKeys<S>>(name: K, builder: RegistrationBuilder<S, NonNullable<S[K]>>): this;
41 override<K extends ConfigurableKeys<S>>(services: { [name in K]: RegistrationBuilder<S, NonNullable<S[K]>> }): this;
41 override<K extends ConfigurableKeys<S>>(services: { [name in K]: RegistrationBuilder<S, NonNullable<S[K]>> }): this;
42
42
43 lifetime(lifetime: "singleton", typeId: string | number | object): this;
43 lifetime(lifetime: "singleton", typeId: string | number | object): this;
44 lifetime(lifetime: ILifetime<T> | Exclude<ActivationType, "singleton">): this;
44 lifetime(lifetime: ILifetime<T> | Exclude<ActivationType, "singleton">): this;
45
45
46 cleanup(cb: (item: T) => void): this;
46 cleanup(cb: (item: T) => void): this;
47
47
48 value(v: T): void;
48 value(v: T): void;
49 }
49 }
50
50
51 export type RegistrationBuilder<S extends object, T> = (d: DescriptorBuilder<S, T>) => void;
51 export type RegistrationBuilder<S extends object, T> = (d: DescriptorBuilder<S, T>) => void;
52
52
53 export type RegistrationBuildersMap<S extends object, K extends ConfigurableKeys<S> = ConfigurableKeys<S>> = {
53 export type RegistrationBuildersMap<S extends object, K extends ConfigurableKeys<S> = ConfigurableKeys<S>> = {
54 [k in K]-?: RegistrationBuilder<ContainerServices<S>, NonNullable<ConfigurableServices<S>[k]>>
54 [k in K]-?: RegistrationBuilder<ContainerServices<S>, NonNullable<ConfigurableServices<S>[k]>>
55 };
55 };
56
56
57 export interface Descriptor<S extends object, T> {
57 export interface Descriptor<S extends object, T> {
58 activate(context: ActivationContext<S>): T;
58 activate(context: ActivationContext<S>): T;
59 }
59 }
60
60
61 export type ConfigurableDescriptor<S extends object, K extends ConfigurableKeys<S>> = Descriptor<ContainerServices<S>, ConfigurableServices<S>[K]>;
61 export type ConfigurableDescriptor<S extends object, K extends ConfigurableKeys<S>> = Descriptor<ContainerServices<S>, ConfigurableServices<S>[K]>;
62
62
63 export type RegistrationMap<S extends object, K extends keyof S = keyof S> = {
63 export type RegistrationMap<S extends object, K extends keyof S = keyof S> = {
64 [k in K]-?: Descriptor<S, S[k]>;
64 [k in K]-?: Descriptor<S, S[k]>;
65 };
65 };
66
66
67 export interface ProvidedServices<S extends object> {
67 export interface ProvidedServices<S extends object> {
68 container: ServiceLocator<ContainerServices<S>>;
68 container: ServiceLocator<ContainerServices<S>>;
69
69
70 childContainer: ServiceContainer<S>;
70 childContainer: ServiceContainer<S>;
71 }
71 }
72
72
73 export type ProvidedKeys = keyof ProvidedServices<object>;
73 export type ProvidedKeys = keyof ProvidedServices<object>;
74
74
75 export type ContainerKeys<S extends object> = keyof ContainerServices<S>;
75 export type ContainerKeys<S extends object> = keyof ContainerServices<S>;
76
76
77 export type Mix<S, X> = { [k in keyof (S & X)]: k extends keyof X ? X[k] : S[k & keyof S] };
77 export type Mix<S, X> = { [k in keyof (S & X)]: k extends keyof X ? X[k] : S[k & keyof S] };
78
78
79 export type ContainerServices<S extends object> = Mix<S, ProvidedServices<S>>;
79 export type ContainerServices<S extends object> = Mix<S, ProvidedServices<S>>;
80
80
81 export type ConfigurableKeys<S extends object> = Exclude<keyof S, ProvidedKeys>;
81 export type ConfigurableKeys<S extends object> = Exclude<keyof S, ProvidedKeys>;
82
82
83 export type ConfigurableServices<S extends object> = Pick<S, ConfigurableKeys<S>>;
83 export type ConfigurableServices<S extends object> = Pick<S, ConfigurableKeys<S>>;
84
84
85 export interface ServiceLocator<S extends object> {
85 export interface ServiceLocator<S extends object> {
86 resolve<K extends keyof S>(name: K): NonNullable<S[K]>;
86 resolve<K extends keyof S>(name: K): NonNullable<S[K]>;
87 resolve<K extends keyof S, T>(name: K, def: T): NonNullable<S[K]> | T;
87 resolve<K extends keyof S, T>(name: K, def: T): NonNullable<S[K]> | T;
88 }
88 }
89
89
90 export interface LifetimeContainer {
90 export interface LifetimeContainer {
91 createLifetime<T>(): ILifetime<T>;
91 createLifetime<T>(): ILifetime<T>;
92 }
92 }
93
93
94 export interface ServiceContainer<S extends object> extends ServiceLocator<ContainerServices<S>>, LifetimeContainer, IDestroyable {
94 export interface ServiceContainer<S extends object> extends ServiceLocator<ContainerServices<S>>, LifetimeContainer, IDestroyable {
95
95
96 register<K extends ConfigurableKeys<S>>(name: K, service: ConfigurableDescriptor<S, K>): void;
96 register<K extends ConfigurableKeys<S>>(name: K, service: ConfigurableDescriptor<S, K>): void;
97 register<K extends ConfigurableKeys<S>>(services: { [k in K]: ConfigurableDescriptor<S, K> }): void;
97 register<K extends ConfigurableKeys<S>>(services: { [k in K]: ConfigurableDescriptor<S, K> }): void;
98
98
99 createChildContainer(): ServiceContainer<S>;
99 createChildContainer(): ServiceContainer<S>;
100 }
100 }
101
101
102
102
103 export type ActivationType = "singleton" | "container" | "hierarchy" | "context" | "call";
103 export type ActivationType = "singleton" | "container" | "hierarchy" | "context" | "call";
104
104
105 /**
105 /**
106 * Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ для управлСния Тизнью экзСмпляра ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. КаТдая рСгистрация ΠΈΠΌΠ΅Π΅Ρ‚
106 * Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ для управлСния Тизнью экзСмпляра ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. КаТдая рСгистрация ΠΈΠΌΠ΅Π΅Ρ‚
107 * свой собствСнный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ `ILifetime`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСтся ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΠΈ
107 * свой собствСнный ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ `ILifetime`, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ создаСтся ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Π°ΠΊΡ‚ΠΈΠ²Π°Ρ†ΠΈΠΈ
108 */
108 */
109 export interface ILifetime<T> {
109 export interface ILifetime<T> {
110 /** ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ ΡƒΠΆΠ΅ создан экзСмпляр ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° */
110 /** ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ ΡƒΠΆΠ΅ создан экзСмпляр ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° */
111 has(): boolean;
111 has(): boolean;
112
112
113 get(): T;
113 get(): T;
114
114
115 initialize(context: ActivationContext<object>): void;
115 initialize(context: ActivationContext<object>): void;
116
116
117 store(item: T, cleanup?: (item: T) => void): void;
117 store(item: T, cleanup?: (item: T) => void): void;
118 }
118 }
119
119
120 export type RequiredKeys<T, K extends keyof T = keyof T> = keyof { [p in K as (T[p] extends undefined ? never : p)]-?: T[p] };
120 export type ExtractRequired<T, K extends keyof T = keyof T> = { [p in K as (undefined extends T[p] ? never : p)]-?: T[p] };
121
121
@@ -1,58 +1,58
1 /* eslint max-classes-per-file: ["error", 20] */
1 /* eslint max-classes-per-file: ["error", 20] */
2 import { describe, it } from "mocha";
2 import { describe, it } from "mocha";
3 import {LifetimeManager} from "../LifetimeManager";
3 import {LifetimeManager} from "../LifetimeManager";
4 import {Container} from "../Container";
4 import {Container} from "../Container";
5 import { fluent } from "../traits";
5 import { fluent } from "../traits";
6
6
7 class Foo {
7 class Foo {
8 foo = "foo";
8 foo = "foo";
9 }
9 }
10
10
11 class Bar {
11 class Bar {
12 bar = "bar";
12 bar = "bar";
13
13
14 constructor(foo?: () => Foo) {}
14 constructor(foo?: () => Foo) {}
15 }
15 }
16
16
17 interface Services {
17 interface Services {
18 foo: Foo;
18 foo: Foo;
19
19
20 bar?: Bar;
20 bar?: Bar;
21
21
22 baz: Foo;
22 baz: Foo;
23 }
23 }
24
24
25 interface ServicesB {
25 interface ServicesB {
26 // will give errors
26 // will give errors
27 // baz: Bar;
27 // baz: Bar;
28
28
29 baz: Foo;
29 baz: Foo;
30
30
31 zoo?: Foo;
31 zoo?: Foo;
32 }
32 }
33
33
34 interface SharedServices {
34 interface SharedServices {
35 foo: Foo;
35 foo: Foo;
36
36
37 bar?: Bar;
37 bar?: Bar;
38
38
39 baz: Bar;
39 baz: Bar;
40 }
40 }
41
41
42 const config = fluent()
42 const config = fluent()
43 .declare<Services>()
43 .declare<Services>()
44 .declare<ServicesB>()
44 .declare<ServicesB>()
45 .register({
45 .register({
46 bar: it => it
46 bar: it => it
47 .lifetime("context")
47 .lifetime("context")
48 .factory($ => new Bar($("zoo", {lazy: true, default: new Foo()}))),
48 .factory($ => new Bar($("zoo", {lazy: true, default: new Foo()}))),
49 foo: it => it.factory($ => new Foo()),
49 foo: it => it.factory($ => new Foo()),
50 baz: it => it.value(new Foo())
50 baz: it => it.value(new Foo())
51 })
51 })
52 .done();
52 .done({});
53
53
54 declare const container: Container<SharedServices>;
54 declare const container: Container<SharedServices>;
55
55
56 const c2 = config.apply(container);
56 const c2 = config.apply(container);
57
57
58 c2.resolve("baz"); No newline at end of file
58 c2.resolve("baz");
General Comments 0
You need to be logged in to leave comments. Login now