##// END OF EJS Templates
WIP lifetime, service descriptors
cin -
r14:3f8a82c8ce73 default
parent child
Show More
@@ -1,5 +1,5
1 1 import { ActivationError } from "./ActivationError";
2 import { Descriptor, ILifetime, IActivationContext, DescriptorMap, ILifetimeManager } from "./interfaces";
2 import { Descriptor, ILifetime, IActivationContext, DescriptorMap, ILifetimeManager, ILifetimeSlot } from "./interfaces";
3 3 import { argumentNotNull, prototype } from "./traits";
4 4
5 5 export interface ActivationContextInfo {
@@ -85,6 +85,18 export class ActivationContext<S> implem
85 85 this._services[name] = service;
86 86 }
87 87
88 ownerSlot<T>(slotId: string | number): ILifetimeSlot<T> {
89 return this._lifetimeManagers[this._service.level].slot(slotId);
90 }
91
92 containerSlot<T>(slotId: string | number): ILifetimeSlot<T> {
93 return this._lifetimeManagers[this._lifetimeManagers.length - 1].slot(slotId);
94 }
95
96 contextSlot<T>(slotId: string | number): ILifetimeSlot<T> {
97
98 }
99
88 100 createLifetime<T>(): ILifetime<T> {
89 101 const id = nextId++;
90 102 return {
@@ -8,7 +8,7 import { isDestroyable, prototype } from
8 8 /**
9 9 * Container builder used to prepare service descriptors and create a IoC container
10 10 */
11 export class ContainerBuilder<S extends ContainerServicesConstraint<S>, U extends keyof S> implements
11 export class ContainerBuilder<S, U extends keyof S> implements
12 12 IContainerBuilder<S, U> {
13 13
14 14 private _pending = 1;
@@ -20,12 +20,7 export class ContainerBuilder<S extends
20 20 private readonly _lifetime: ILifetime<IDestroyable>;
21 21
22 22 constructor(parentServices: DescriptorMap<S> | null = null, lifetime?: ILifetime<IDestroyable>) {
23 this._services = {
24 ...parentServices,
25 container: containerSelfDescriptor as any,
26 childContainer: containerSelfDescriptor as any
27 };
28 this._lifetimeManager = new LifetimeManager();
23 this._services = { ...parentServices }; // create a copy
29 24 this._lifetime = lifetime ?? emptyLifetime();
30 25 }
31 26 createServiceBuilder<K extends U>(name: K):
@@ -1,7 +1,7
1 1 import { BuildDescriptorFn, IDescriptorBuilder, DepsMap, Resolve, DescriptorMap } from "./interfaces";
2 2 import { Descriptor, ILifetime, ActivationType } from "./interfaces";
3 3 import { DescriptorImpl } from "./DescriptorImpl";
4 import { contextLifetime, emptyLifetime, hierarchyLifetime, LifetimeManager, singletonLifetime } from "./LifetimeManager";
4 import { containerLifetime, contextLifetime, emptyLifetime, hierarchyLifetime, LifetimeManager, singletonLifetime } from "./LifetimeManager";
5 5 import { each, isPromise, isString, key, oid } from "./traits";
6 6
7 7 /**
@@ -9,14 +9,13 import { each, isPromise, isString, key,
9 9 * @template {T} Тип сервиса
10 10 */
11 11 export class DescriptorBuilder<S, T, R, U extends keyof S> implements IDescriptorBuilder<S, T, R, U> {
12 private readonly _lifetimeManager: LifetimeManager;
13 12 private readonly _cb: (d: Descriptor<S, T>) => void;
14 13
15 14 private readonly _eb: (err: unknown) => void;
16 15
17 16 private readonly _refs: DepsMap<R>;
18 17
19 private _lifetime = emptyLifetime<T>();
18 private _lifetime: ILifetime<T> = emptyLifetime<T>();
20 19
21 20 private _overrides: DescriptorMap<S>;
22 21
@@ -34,12 +33,10 export class DescriptorBuilder<S, T, R,
34 33 * Creates new DescriptorBuilder. Accepts a lifetime container for resolving "container"
35 34 * lifetime.
36 35 *
37 * @param lifetimeManager The lifetime container is the container where the service is to be registered.
38 36 * @param cb The callback to receive the built service descriptor
39 37 * @param eb The callback to receive the error due
40 38 */
41 constructor(lifetimeManager: LifetimeManager, cb: (d: Descriptor<S, T>) => void, eb: (err: unknown) => void) {
42 this._lifetimeManager = lifetimeManager;
39 constructor(cb: (d: Descriptor<S, T>) => void, eb: (err: unknown) => void) {
43 40 this._cb = cb;
44 41 this._eb = eb;
45 42 this._overrides = {};
@@ -88,7 +85,6 export class DescriptorBuilder<S, T, R,
88 85 if (builder) {
89 86 this._defer();
90 87 const d = new DescriptorBuilder<S, NonNullable<S[K]>, object, U>(
91 this._lifetimeManager,
92 88 result => {
93 89 this._overrides[nameOrServices] = result;
94 90 this._complete();
@@ -149,7 +145,7 export class DescriptorBuilder<S, T, R,
149 145 _resolveLifetime<T>(activation: ActivationType, typeId?: string | object): ILifetime<T> {
150 146 switch (activation) {
151 147 case "container":
152 return this._lifetimeManager.create();
148 return containerLifetime();
153 149 case "hierarchy":
154 150 return hierarchyLifetime();
155 151 case "context":
@@ -2,15 +2,16 import { Descriptor, ILifetime, DepsMap,
2 2 import { each, key } from "./traits";
3 3
4 4 export interface DescriptorImplArgs<S, T> {
5 lifetime: ILifetime<T>;
6 5
7 factory: (refs: Record<key, unknown>) => NonNullable<T>;
6 readonly lifetime: ILifetime<NonNullable<T>>;
7
8 readonly factory: (refs: Record<key, unknown>) => NonNullable<T>;
8 9
9 cleanup?: (item: NonNullable<T>) => void;
10 readonly cleanup?: (item: NonNullable<T>) => void;
10 11
11 overrides?: DescriptorMap<S>;
12 readonly overrides?: DescriptorMap<S>;
12 13
13 dependencies?: DepsMap<S>;
14 readonly dependencies?: DepsMap<S>;
14 15 }
15 16
16 17 export const containerSelfDescriptor = <S>() => Object.freeze({
@@ -25,7 +26,7 export class DescriptorImpl<S, T> implem
25 26
26 27 private readonly _overrides?: DescriptorMap<S>;
27 28
28 private readonly _lifetime: ILifetime<T>;
29 private readonly _lifetime: ILifetime<NonNullable<T>>;
29 30
30 31 private readonly _factory: (refs: Record<key, unknown>) => NonNullable<T>;
31 32
@@ -54,7 +55,7 export class DescriptorImpl<S, T> implem
54 55
55 56 if (has())
56 57 return get();
57
58
58 59 initialize();
59 60
60 61 if (this._overrides)
@@ -87,12 +88,12 export class DescriptorImpl<S, T> implem
87 88
88 89 try {
89 90 // call the factory method
90 const instance = (0,this._factory)(refs);
91
91 const instance = (0, this._factory)(refs);
92
92 93 // store the instance
93 94 store(instance, this._cleanup);
94 95 return instance;
95 } catch(err) {
96 } catch (err) {
96 97 context.fail(err);
97 98 }
98 99 }
@@ -158,10 +158,6 export type ContainerServicesConstraint<
158 158
159 159 export interface Descriptor<S, T> {
160 160
161 /** The level of the service in the containers chain.
162 */
163 readonly level: number;
164
165 161 /** This flags indicates that this registration can be replaced or overridden. */
166 162 readonly configurable?: boolean;
167 163
@@ -252,7 +248,7 export type ActivationType = "singleton"
252 248 * Интерфейс для управления жизнью экземпляра объекта. Каждая регистрация имеет
253 249 * свой собственный объект `ILifetime`, который создается при первой активации
254 250 */
255 export type ILifetime<T> = (context: ILifetimeContext) => ILifetimeSlot<NonNullable<T>>;
251 export type ILifetime<T> = (context: ILifetimeContext) => ILifetimeSlot<T>;
256 252
257 253 export interface ILifetimeSlot<T> {
258 254 readonly has: () => boolean;
General Comments 0
You need to be logged in to leave comments. Login now