feat(blog): add per-feature InversifyJS container (symbols, module, container)

This commit is contained in:
2026-05-04 22:14:56 +02:00
parent 41d7883e7a
commit c00283506c
5 changed files with 65 additions and 1 deletions

View File

@@ -0,0 +1,36 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { blogContainer } from "./container";
import { BLOG_SYMBOLS } from "./symbols";
import { BlogModule } from "./module";
import { MockArticlesRepository } from "@/infrastructure/repositories/mock-articles.repository";
import type { IArticlesRepository } from "@/application/repositories/articles-repository.interface";
describe("blogContainer", () => {
beforeEach(() => {
blogContainer.unbindAll();
blogContainer.load(BlogModule);
});
afterEach(() => {
blogContainer.unbindAll();
});
it("resolves IArticlesRepository to MockArticlesRepository by default binding", () => {
const repo = blogContainer.get<IArticlesRepository>(
BLOG_SYMBOLS.IArticlesRepository,
);
expect(repo).toBeInstanceOf(MockArticlesRepository);
});
it("supports rebinding to a custom repo", () => {
blogContainer.unbind(BLOG_SYMBOLS.IArticlesRepository);
const custom = new MockArticlesRepository();
blogContainer
.bind<IArticlesRepository>(BLOG_SYMBOLS.IArticlesRepository)
.toConstantValue(custom);
const resolved = blogContainer.get<IArticlesRepository>(
BLOG_SYMBOLS.IArticlesRepository,
);
expect(resolved).toBe(custom);
});
});

View File

@@ -0,0 +1,6 @@
import "reflect-metadata";
import { Container } from "inversify";
import { BlogModule } from "./module";
export const blogContainer = new Container({ defaultScope: "Singleton" });
blogContainer.load(BlogModule);

View File

@@ -0,0 +1,11 @@
import { ContainerModule, type interfaces } from "inversify";
import type { IArticlesRepository } from "@/application/repositories/articles-repository.interface";
import { MockArticlesRepository } from "@/infrastructure/repositories/mock-articles.repository";
import { BLOG_SYMBOLS } from "./symbols";
export const BlogModule = new ContainerModule((bind: interfaces.Bind) => {
bind<IArticlesRepository>(BLOG_SYMBOLS.IArticlesRepository).to(
MockArticlesRepository,
);
});

View File

@@ -0,0 +1,3 @@
export const BLOG_SYMBOLS = {
IArticlesRepository: Symbol.for("blog:IArticlesRepository"),
} as const;

View File

@@ -1,3 +1,11 @@
import path from "path";
import { baseVitestConfig } from "@repo/typescript-config/vitest.base"; import { baseVitestConfig } from "@repo/typescript-config/vitest.base";
export default baseVitestConfig; export default {
...baseVitestConfig,
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
};