Oussama SAIDI

0 %
Oussama SAIDI
Consultant .Net
Sharepoint Office 365

  • Résidence:
    France
  • Ville:
    Lille
Arabe
Français
Anglais
.Net
Html/Css/Js
Web Api
Base de données
  • C#,.Net Core, .Net MVC
  • Rest Api
  • Docker
  • GIT,TFS

.Net 8 Domain Driven Design l’Architecture Propre et simple

avril 4, 2025

Introduction

Dans le développement d’applications .NET Core robustes et maintenables, l’adoption d’une architecture propre (Clean Architecture) combinée au Domain Driven Design (DDD) représente une approche puissante. Ce guide complet vous présente une implémentation structurée, parfaite pour vos projets d’entreprise.

Dans cet article

Pourquoi Choisir cette Architecture Pour Domain Driven Design ?

  • Séparation claire des responsabilités : Chaque couche a un rôle bien défini
  • Indépendance technologique : Le domaine métier ne dépend d’aucune technologie spécifique
  • Testabilité accrue : Isolation des composants pour des tests unitaires efficaces
  • Évolutivité : Adaptation facile aux changements métiers ou techniques
  • Maintenabilité : Code organisé pour une longue durée de vie

Structure de la Solution

VotreSolution/
├── src/
│   ├── VotreSolution.Domain/         # Cœur métier
│   ├── VotreSolution.Application/    # Logique applicative
│   ├── VotreSolution.Infrastructure/ # Implémentations techniques
│   ├── VotreSolution.WebApi/         # Interface HTTP
│   └── VotreSolution.Tests/          # Tests automatisés

1. Domain Driven Design Couche Domain : Le Cœur Métier

Objectif : Contient toute la logique métier sous forme d’entités, objets-valeurs, agrégats et services de domaine.

Structure Recommandée :

Domain/
├── Entites/
│   ├── Produit.cs                   # Exemple d'agrégat racine
│   └── Commande.cs                  
├── ObjetsValeurs/
│   ├── Adresse.cs
│   └── Montant.cs
├── Evenements/
│   ├── CommandeCreeeEvent.cs
│   └── EvenementMetier.cs          # Événement de base
├── Exceptions/
│   └── ExceptionMetier.cs
├── Interfaces/
│   └── IDepot.cs                  # Interface générique de dépôt
├── Services/
│   └── IServiceMetier.cs          
└── Specifications/                 # Modèle de spécification
    └── ProduitDisponibleSpec.cs

Caractéristiques Clés :

  • Aucune dépendance externe
  • Pure logique métier
  • Définit les interfaces de persistence
  • Contient les événements métier

Exemple d’entité avec comportement :

public class Produit : Entite, IAggregateRoot
{
    public string Nom { get; private set; }
    public Montant Prix { get; private set; }
    public int Stock { get; private set; }

    public void MettreAJourStock(int quantite)
    {
        if (quantite < 0) 
            throw new ExceptionMetier("Le stock ne peut être négatif");
        
        Stock = quantite;
        AjouterEvenement(new StockProduitModifieEvent(this));
    }
}

2. Domain Driven Design Couche Application : Orchestration des Cas d’Usage

Objectif : Gère les flux applicatifs, les DTOs et coordonne les opérations.

Organisation Optimale :

Application/
├── Commandes/
│   ├── CreerProduitCommande.cs
│   └── CreerProduitHandler.cs
├── Requetes/
│   ├── ObtenirProduitParId.cs
│   └── ObtenirProduitParIdHandler.cs
├── DTOs/
│   ├── ProduitDto.cs
│   └── DetailsProduitDto.cs
├── Interfaces/
│   ├── IEmailService.cs          
│   └── IUtilisateurCourantService.cs
├── Mappings/
│   └── ProfilAutoMapper.cs
└── Comportements/
    ├── ValidationBehavior.cs     # Pipeline MediatR
    └── LoggingBehavior.cs

Bonnes Pratiques :

  • Utilisation du motif CQRS
  • Gestion des transactions
  • Validation des requêtes
  • Mapping DTO/Entités

Exemple de gestionnaire de commande :

public class CreerProduitHandler 
    : IRequestHandler<CreerProduitCommande, Resultat<int>>
{
    private readonly IDepotProduit _depot;
    private readonly IMapper _mapper;
    
    public CreerProduitHandler(IDepotProduit depot, IMapper mapper)
    {
        _depot = depot;
        _mapper = mapper;
    }

    public async Task<Resultat<int>> Handle(
        CreerProduitCommande requete, 
        CancellationToken cancellationToken)
    {
        var produit = _mapper.Map<Produit>(requete);
        
        await _depot.AjouterAsync(produit);
        await _depot.UnitOfWork.SauvegarderAsync(cancellationToken);
        
        return Resultat<int>.Succes(produit.Id);
    }
}

3. Domain Driven Design Couche Infrastructure : Implémentations Techniques

Objectif : Fournit les implémentations concrètes des interfaces définies dans les couches supérieures.

Composants Essentiels :

Infrastructure/
├── Data/
│   ├── ApplicationDbContext.cs     # Configuration EF Core
│   └── Migrations/               
├── Depots/
│   ├── DepotProduit.cs          
│   └── DepotGenerique.cs         
├── Services/
│   ├── HorlogeSysteme.cs          # Abstraction du temps
│   └── ServiceEmail.cs          
└── BusEvenements/
    ├── BusEvenementsRabbitMQ.cs  
    └── BusEvenementsMemoire.cs  

Points Forts :

  • Implémentation de la persistence
  • Communication externe
  • Services techniques
  • Facilement remplaçable

4. Domain Driven Design Couche WebApi : Point d’Entrée HTTP

Objectif : Exposer les fonctionnalités via une API REST.

Structure Type :

WebApi/
├── Controllers/
│   ├── ProduitsController.cs
│   └── CommandesController.cs
├── Middleware/
│   ├── GestionErreursMiddleware.cs
│   └── LoggingMiddleware.cs
├── Extensions/
│   ├── ServiceExtensions.cs       # Configuration DI
│   └── SwaggerExtensions.cs
└── Program.cs                    # Configuration initiale

Exemple de contrôleur API :

[ApiController]
[Route("api/[controller]")]
public class ProduitsController : ControllerBase
{
    private readonly IMediateur _mediateur;

    public ProduitsController(IMediateur mediateur)
    {
        _mediateur = mediateur;
    }

    [HttpPost]
    public async Task<IActionResult> Creer(
        [FromBody] CreerProduitCommande commande)
    {
        var resultat = await _mediateur.Send(commande);
        return resultat.Match(
            id => CreatedAtAction(nameof(ObtenirParId), new { id }, id),
            erreurs => Problem(erreurs));
    }
}

Flux des Dépendances

WebApi → Application → Domain
            ↑             ↑
Infrastructure →───────┘

Packages NuGet Recommandés

  • Domain : Aucun (logique pure)
  • Application : MediatR, FluentValidation, AutoMapper
  • Infrastructure : EntityFrameworkCore, Dapper
  • WebApi : ASP.NET Core, Swashbuckle

Avantages pour votre Projet

  1. Adaptabilité : Changement de SGBD sans impact sur le métier
  2. Testabilité : Mocking facile des dépendances
  3. Évolutivité : Ajout de fonctionnalités sans risque de régression
  4. Sécurité : Isolation des préoccupations sensibles
  5. Performance : Optimisation possible par couche

Conclusion

Cette architecture propre combinée à Domain Driven Design offre un cadre solide pour développer des applications .NET Core maintenables et évolutives. En séparant clairement les préoccupations métiers des aspects techniques, vous gagnez en flexibilité et réduisez la dette technique.

Prochaine Étape : Implémentez cette structure dans votre prochain projet et observez la différence en termes de qualité de code et de productivité !

Ressources supplémentaires : Concevoir un microservice orienté DDD


Vous avez des questions sur une partie spécifique de cette architecture ? Partagez-les dans les commentaires !

Nos Derniers Articles

Publié dans .Net Core, Api, Asp .Net, c#, Design, ef core, entity framework core, entity-framework-core, SOLIDTags:
© 2024 Tous les droits sont réservés.
oussamasaidi.com