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.

Informations de source

Dépôt
j4flmao/agent_skills_nodejs_nestjs
Dernière activité de la source
3 mai 2026 à 03:46
Langue détectée de SKILL.md
anglais
Étoiles
1
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
4 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
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.
Voir sur GitHub