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에서 보기