# HG changeset patch # User cin # Date 2023-10-01 10:26:32 # Node ID 3f8a82c8ce7388337215bfb9ba15addddb85845a # Parent dc3d64c435739f44e7236416243b2d995b2d2f8c WIP lifetime, service descriptors diff --git a/src/main/ts/ActivationContext.ts b/src/main/ts/ActivationContext.ts --- a/src/main/ts/ActivationContext.ts +++ b/src/main/ts/ActivationContext.ts @@ -1,5 +1,5 @@ import { ActivationError } from "./ActivationError"; -import { Descriptor, ILifetime, IActivationContext, DescriptorMap, ILifetimeManager } from "./interfaces"; +import { Descriptor, ILifetime, IActivationContext, DescriptorMap, ILifetimeManager, ILifetimeSlot } from "./interfaces"; import { argumentNotNull, prototype } from "./traits"; export interface ActivationContextInfo { @@ -85,6 +85,18 @@ export class ActivationContext implem this._services[name] = service; } + ownerSlot(slotId: string | number): ILifetimeSlot { + return this._lifetimeManagers[this._service.level].slot(slotId); + } + + containerSlot(slotId: string | number): ILifetimeSlot { + return this._lifetimeManagers[this._lifetimeManagers.length - 1].slot(slotId); + } + + contextSlot(slotId: string | number): ILifetimeSlot { + + } + createLifetime(): ILifetime { const id = nextId++; return { diff --git a/src/main/ts/ContainerBuilder.ts b/src/main/ts/ContainerBuilder.ts --- a/src/main/ts/ContainerBuilder.ts +++ b/src/main/ts/ContainerBuilder.ts @@ -8,7 +8,7 @@ import { isDestroyable, prototype } from /** * Container builder used to prepare service descriptors and create a IoC container */ -export class ContainerBuilder, U extends keyof S> implements +export class ContainerBuilder implements IContainerBuilder { private _pending = 1; @@ -20,12 +20,7 @@ export class ContainerBuilder; constructor(parentServices: DescriptorMap | null = null, lifetime?: ILifetime) { - this._services = { - ...parentServices, - container: containerSelfDescriptor as any, - childContainer: containerSelfDescriptor as any - }; - this._lifetimeManager = new LifetimeManager(); + this._services = { ...parentServices }; // create a copy this._lifetime = lifetime ?? emptyLifetime(); } createServiceBuilder(name: K): diff --git a/src/main/ts/DescriptorBuilder.ts b/src/main/ts/DescriptorBuilder.ts --- a/src/main/ts/DescriptorBuilder.ts +++ b/src/main/ts/DescriptorBuilder.ts @@ -1,7 +1,7 @@ import { BuildDescriptorFn, IDescriptorBuilder, DepsMap, Resolve, DescriptorMap } from "./interfaces"; import { Descriptor, ILifetime, ActivationType } from "./interfaces"; import { DescriptorImpl } from "./DescriptorImpl"; -import { contextLifetime, emptyLifetime, hierarchyLifetime, LifetimeManager, singletonLifetime } from "./LifetimeManager"; +import { containerLifetime, contextLifetime, emptyLifetime, hierarchyLifetime, LifetimeManager, singletonLifetime } from "./LifetimeManager"; import { each, isPromise, isString, key, oid } from "./traits"; /** @@ -9,14 +9,13 @@ import { each, isPromise, isString, key, * @template {T} Тип сервиса */ export class DescriptorBuilder implements IDescriptorBuilder { - private readonly _lifetimeManager: LifetimeManager; private readonly _cb: (d: Descriptor) => void; private readonly _eb: (err: unknown) => void; private readonly _refs: DepsMap; - private _lifetime = emptyLifetime(); + private _lifetime: ILifetime = emptyLifetime(); private _overrides: DescriptorMap; @@ -34,12 +33,10 @@ export class DescriptorBuilder) => void, eb: (err: unknown) => void) { - this._lifetimeManager = lifetimeManager; + constructor(cb: (d: Descriptor) => void, eb: (err: unknown) => void) { this._cb = cb; this._eb = eb; this._overrides = {}; @@ -88,7 +85,6 @@ export class DescriptorBuilder, object, U>( - this._lifetimeManager, result => { this._overrides[nameOrServices] = result; this._complete(); @@ -149,7 +145,7 @@ export class DescriptorBuilder(activation: ActivationType, typeId?: string | object): ILifetime { switch (activation) { case "container": - return this._lifetimeManager.create(); + return containerLifetime(); case "hierarchy": return hierarchyLifetime(); case "context": diff --git a/src/main/ts/DescriptorImpl.ts b/src/main/ts/DescriptorImpl.ts --- a/src/main/ts/DescriptorImpl.ts +++ b/src/main/ts/DescriptorImpl.ts @@ -2,15 +2,16 @@ import { Descriptor, ILifetime, DepsMap, import { each, key } from "./traits"; export interface DescriptorImplArgs { - lifetime: ILifetime; - factory: (refs: Record) => NonNullable; + readonly lifetime: ILifetime>; + + readonly factory: (refs: Record) => NonNullable; - cleanup?: (item: NonNullable) => void; + readonly cleanup?: (item: NonNullable) => void; - overrides?: DescriptorMap; + readonly overrides?: DescriptorMap; - dependencies?: DepsMap; + readonly dependencies?: DepsMap; } export const containerSelfDescriptor = () => Object.freeze({ @@ -25,7 +26,7 @@ export class DescriptorImpl implem private readonly _overrides?: DescriptorMap; - private readonly _lifetime: ILifetime; + private readonly _lifetime: ILifetime>; private readonly _factory: (refs: Record) => NonNullable; @@ -54,7 +55,7 @@ export class DescriptorImpl implem if (has()) return get(); - + initialize(); if (this._overrides) @@ -87,12 +88,12 @@ export class DescriptorImpl implem try { // call the factory method - const instance = (0,this._factory)(refs); - + const instance = (0, this._factory)(refs); + // store the instance store(instance, this._cleanup); return instance; - } catch(err) { + } catch (err) { context.fail(err); } } diff --git a/src/main/ts/interfaces.ts b/src/main/ts/interfaces.ts --- a/src/main/ts/interfaces.ts +++ b/src/main/ts/interfaces.ts @@ -158,10 +158,6 @@ export type ContainerServicesConstraint< export interface Descriptor { - /** The level of the service in the containers chain. - */ - readonly level: number; - /** This flags indicates that this registration can be replaced or overridden. */ readonly configurable?: boolean; @@ -252,7 +248,7 @@ export type ActivationType = "singleton" * Интерфейс для управления жизнью экземпляра объекта. Каждая регистрация имеет * свой собственный объект `ILifetime`, который создается при первой активации */ -export type ILifetime = (context: ILifetimeContext) => ILifetimeSlot>; +export type ILifetime = (context: ILifetimeContext) => ILifetimeSlot; export interface ILifetimeSlot { readonly has: () => boolean;