Skip to main content

decoupling-with-di

Decouples modules using ports, adapters, and a DI container (tsyringe / inversify / NestJS). Use when wiring services, removing direct imports of concrete classes, or breaking circular dependencies.

ソース情報

リポジトリ
j4flmao/agent_skills_nodejs_nestjs
ソースの最終更新活動
2026年5月3日 03:46
検出された SKILL.md の言語
英語
スター
1
フォーク
0

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
4 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
decoupling-with-di
description
Decouples modules using ports, adapters, and a DI container (tsyringe / inversify / NestJS). Use when wiring services, removing direct imports of concrete classes, or breaking circular dependencies.
license
MIT
# Decoupling with DI ## When to use - Wiring services and repositories - Removing direct imports of concrete classes - Breaking circular dependencies - Switching DI containers ## Core rules 1. Domain/application declare **ports** (interfaces), infrastructure implements them 2. Classes receive collaborators via **constructor injection** 3. No direct imports of concrete classes across layers 4. Use DI container (tsyringe, inversify, or NestJS built-in) 5. Layer dependency: `infrastructure → application → domain` ## Reference shape (TypeScript) ### Port (Interface in Application Layer) ```typescript // src/application/ports/user.repository.ts export interface UserRepository { findById(id: string): Promise<User | null>; save(user: User): Promise<User>; } ``` ### Adapter (Implementation in Infrastructure) ```typescript // src/infrastructure/repositories/typeorm-user.repository.ts @injectable() export class TypeOrmUserRepository implements UserRepository { constructor(private ormRepo: Repository<UserOrmEntity>) {} async findById(id: string): Promise<User | null> { /* ... */ } async save(user: User): Promise<User> { /* ... */ } } ``` ### Consumer (Use-Case) ```typescript // src/application/use-cases/create-user.use-case.ts @injectable() export class CreateUserUseCase { constructor(@inject('UserRepository') private readonly repo: UserRepository) {} } ``` ## Examples — Do ```typescript // Decoupled: depends on interface class OrderService { constructor(private readonly repo: OrderRepository) {} } ``` ## Examples — Don't ```typescript // ❌ Direct import of concrete class import { TypeOrmOrderRepository } from '../infrastructure/typeorm-order.repository'; class OrderService { private repo = new TypeOrmOrderRepository(); // Hard-wired } ``` ## Checklist - [ ] Ports (interfaces) defined in application/domain - [ ] Adapters implement ports in infrastructure - [ ] All dependencies injected via constructor - [ ] No concrete imports across layers - [ ] DI container configured See [reference/di-patterns.md](./reference/di-patterns.md) for full patterns.
GitHubで見る