Skip to content

Commit 95db24e

Browse files
committed
fix: resolve instances from all parent containers
1 parent 2868398 commit 95db24e

14 files changed

+769
-398
lines changed

.changeset/rare-dryers-count.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@webiny/di": patch
3+
---
4+
5+
resolve instances from all parent containers

__tests__/container.test.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
isDecorator,
88
createComposite,
99
isComposite
10-
} from "~/index.js";
10+
} from "../src/index.js";
1111
// Mock implementations for testing
1212
interface ILogger {
1313
log(...args: unknown[]): void;
@@ -284,6 +284,69 @@ describe("DIContainer", () => {
284284
expect(manager.loggers.some(logger => logger instanceof FileLogger)).toBe(true);
285285
});
286286

287+
test("should resolve all implementations from all parent containers when `multiple: true` is used", () => {
288+
const consoleLoggerImpl = createImplementation({
289+
abstraction: LoggerAbstraction,
290+
implementation: ConsoleLogger,
291+
dependencies: []
292+
});
293+
const fileLoggerImpl = createImplementation({
294+
abstraction: LoggerAbstraction,
295+
implementation: FileLogger,
296+
dependencies: []
297+
});
298+
299+
const childContainer1 = rootContainer.createChildContainer();
300+
301+
rootContainer.register(consoleLoggerImpl).inSingletonScope();
302+
childContainer1.register(fileLoggerImpl).inSingletonScope();
303+
304+
class LoggerManager {
305+
constructor(public loggers: ILogger[]) {}
306+
}
307+
308+
const managerAbstraction = new Abstraction<LoggerManager>("LoggerManager");
309+
310+
const managerImpl = createImplementation({
311+
abstraction: managerAbstraction,
312+
implementation: LoggerManager,
313+
dependencies: [[LoggerAbstraction, { multiple: true }]]
314+
});
315+
316+
const childContainer2 = childContainer1.createChildContainer();
317+
childContainer2.register(managerImpl);
318+
319+
const manager = childContainer2.resolve(managerAbstraction);
320+
expect(manager.loggers.length).toBe(2);
321+
expect(manager.loggers.some(logger => logger instanceof ConsoleLogger)).toBe(true);
322+
expect(manager.loggers.some(logger => logger instanceof FileLogger)).toBe(true);
323+
});
324+
325+
test("should resolve all implementations from all parent containers when`resolveAll` is used", () => {
326+
const consoleLoggerImpl = createImplementation({
327+
abstraction: LoggerAbstraction,
328+
implementation: ConsoleLogger,
329+
dependencies: []
330+
});
331+
const fileLoggerImpl = createImplementation({
332+
abstraction: LoggerAbstraction,
333+
implementation: FileLogger,
334+
dependencies: []
335+
});
336+
337+
const childContainer1 = rootContainer.createChildContainer();
338+
339+
rootContainer.register(consoleLoggerImpl).inSingletonScope();
340+
childContainer1.register(fileLoggerImpl).inSingletonScope();
341+
342+
const childContainer2 = childContainer1.createChildContainer();
343+
344+
const loggers = childContainer2.resolveAll(LoggerAbstraction);
345+
expect(loggers.length).toBe(2);
346+
expect(loggers.some(logger => logger instanceof ConsoleLogger)).toBe(true);
347+
expect(loggers.some(logger => logger instanceof FileLogger)).toBe(true);
348+
});
349+
287350
test("should apply decorators to implementation", () => {
288351
class LoggerDecorator implements ILogger {
289352
constructor(private decoratee: ILogger) {}

0 commit comments

Comments
 (0)