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