# HG changeset patch # User cin # Date 2021-04-04 21:27:43 # Node ID 563928fdf335b3f2b51129005510ed9507d962aa # Parent be122e2642864b5784ac3e7c98c3f8a41d7181bc # Parent 7e27596a76a8c5cffb9a43e1523a225a39e7ca4e Merge diff --git a/src/main/ts/di/ActivationContext.ts b/src/main/ts/di/ActivationContext.ts --- a/src/main/ts/di/ActivationContext.ts +++ b/src/main/ts/di/ActivationContext.ts @@ -123,7 +123,7 @@ export class ActivationContext(d: Descriptor, name: string) { if (trace.isLogEnabled()) - trace.log(`enter ${name} ${d}`); + trace.log("enter {0} {1}", name, d); const ctx = this.enter(d, name); const v = d.activate(ctx); diff --git a/src/main/ts/di/LifetimeManager.ts b/src/main/ts/di/LifetimeManager.ts --- a/src/main/ts/di/LifetimeManager.ts +++ b/src/main/ts/di/LifetimeManager.ts @@ -26,6 +26,10 @@ const emptyLifetime: ILifetime = Object. store() { // does nothing + }, + + toString() { + return `[object EmptyLifetime]`; } }); @@ -42,6 +46,9 @@ const unknownLifetime: ILifetime = Objec }, store() { throw new Error("Can't store a value in the unknown lifetime object"); + }, + toString() { + return `[object UnknownLifetime]`; } }); @@ -112,7 +119,7 @@ export class LifetimeManager implements return emptyLifetime; } - static hierarchyLifetime(): ILifetime { + static hierarchyLifetime() { let _lifetime = unknownLifetime; return { initialize(context: ActivationContext) { @@ -129,11 +136,14 @@ export class LifetimeManager implements }, store(item: any, cleanup?: (item: any) => void) { return _lifetime.store(item, cleanup); + }, + toString() { + return `[object HierarchyLifetime, has=${this.has()}]`; } }; } - static contextLifetime(): ILifetime { + static contextLifetime() { let _lifetime = unknownLifetime; return { initialize(context: ActivationContext) { @@ -149,11 +159,14 @@ export class LifetimeManager implements }, store(item: any) { _lifetime.store(item); + }, + toString() { + return `[object ContextLifetime, has=${this.has()}]`; } }; } - static singletonLifetime(typeId: string): ILifetime { + static singletonLifetime(typeId: string) { argumentNotEmptyString(typeId, "typeId"); let pending = false; return { @@ -173,6 +186,9 @@ export class LifetimeManager implements store(item: any) { singletons[typeId] = item; pending = false; + }, + toString() { + return `[object SingletonLifetime, has=${this.has()}, typeId=${typeId}]`; } }; } @@ -193,6 +209,9 @@ export class LifetimeManager implements }, store(item: any) { _lifetime.store(item); + }, + toString() { + return `[object ContainerLifetime, has=${_lifetime.has()}]` } }; } diff --git a/src/main/ts/di/fluent/DescriptorImpl.ts b/src/main/ts/di/fluent/DescriptorImpl.ts --- a/src/main/ts/di/fluent/DescriptorImpl.ts +++ b/src/main/ts/di/fluent/DescriptorImpl.ts @@ -60,4 +60,7 @@ export class DescriptorImpl { const container = new Container<{ @@ -104,3 +105,21 @@ test("Load configuration from module", a t.assert(!isNull(b1._v), "bar.foo should not be null"); }); + +test("Optional dependency with child container", async t => { + const container = new Container<{ + foo?: Foo; + box: Box; + }>(); + await container.fluent({ + box: it => it.factory($ => new Box($("foo"))) + }); + + const child = await container.createChildContainer() + .fluent({ + foo: it => it.factory(() => new Foo()) + }) + + const box = child.resolve("box"); + t.assert(!isNull(box.getValue()), "'foo' dependency is declared in child container"); +}); \ No newline at end of file