BuildingBlocks

Bibliotheque partagee - CQRS, validation, EFCore, endpoints, audit, caching et exceptions

BuildingBlocks

Les BuildingBlocks sont la bibliotheque partagee de Place API. Ils fournissent les abstractions et implementations transversales utilisees par tous les modules.

Protection : Les BuildingBlocks ne doivent pas etre modifies sans approbation explicite. Les changements affectent tous les modules. Privilegier les methodes d'extension ou les abstractions au niveau du module.

Core/CQRS

Wrappers fins autour de MediatR pour le pattern CQRS :

ICommand / ICommand<T>

public interface ICommand : ICommand<Unit> { }

public interface ICommand<out T> : IRequest<T>
    where T : notnull { }

Represente une operation d'ecriture. Retourne Unit (void) ou un type de resultat.

IQuery<T>

public interface IQuery<out T> : IRequest<T>
    where T : notnull { }

Represente une operation de lecture. Retourne toujours un resultat.

ICommandHandler<TCommand, TResponse>

public interface ICommandHandler<in TCommand, TResponse>
    : IRequestHandler<TCommand, TResponse>
    where TCommand : ICommand<TResponse>
    where TResponse : notnull { }

Handler pour les commandes. L'implementation contient la logique metier.

IQueryHandler<TQuery, TResponse>

public interface IQueryHandler<in TQuery, TResponse>
    : IRequestHandler<TQuery, TResponse>
    where TQuery : IQuery<TResponse>
    where TResponse : notnull { }

Handler pour les queries.

Core/Event

Infrastructure d'evenements de domaine :

InterfaceDescription
IDomainEventInterface marqueur pour les evenements de domaine
IHasDomainEventsEntite qui publie des evenements (DomainEvents, ClearDomainEvents())
IIntegrationEventEvenement d'integration entre modules
IEventInterface de base pour tous les evenements
MessageEnvelopeEnveloppe pour les messages avec metadonnees

IEventMapper / IEventDispatcher

  • IEventMapper : convertit les evenements de domaine en evenements d'integration
  • IEventDispatcher : dispatche les evenements via MediatR
  • CompositeEventMapper : combine plusieurs mappers

Core/Model

Abstractions de base pour les entites :

TypeDescription
IEntityInterface de base avec Id
IVersionInterface de versioning optimiste (long Version)
EntityClasse de base pour les entites
AggregateClasse de base pour les aggregats (racine + evenements de domaine)

Core/Pagination

Interfaces de pagination :

TypeDescription
IPageList<T>Liste paginee avec TotalCount, PageNumber, PageSize
IPageRequestRequete de pagination (Page, PageSize)
IPageQuery<T>Query combinant filtres et pagination

Web

IMinimalEndpoint

Interface que tous les endpoints doivent implementer :

public interface IMinimalEndpoint
{
    IEndpointRouteBuilder MapEndpoint(IEndpointRouteBuilder builder);
}

Les endpoints sont decouverts automatiquement au demarrage via scan d'assemblies.

EndpointConfig

Configuration centralisee des endpoints :

public static class EndpointConfig
{
    public const string BaseApiPath = "api/v{version:apiVersion}";
    public static ApiVersionSet VersionSet { get; private set; }
}

Autres composants Web

TypeDescription
BaseControllerControleur de base (heritage MVC, peu utilise dans le pattern Minimal API)
SlugifyParameterTransformerTransformation des parametres de route en kebab-case
AppOptionsOptions generales de l'application (nom, version)

Validation

ValidationBehavior<TRequest, TResponse>

Pipeline behavior MediatR qui execute automatiquement les validateurs FluentValidation :

public sealed class ValidationBehavior<TRequest, TResponse>
    : IPipelineBehavior<TRequest, TResponse>
    where TRequest : class, IRequest<TResponse>
{
    public async Task<TResponse> Handle(
        TRequest request,
        RequestHandlerDelegate<TResponse> next,
        CancellationToken cancellationToken)
    {
        _validator = _serviceProvider.GetService<IValidator<TRequest>>();
        if (_validator is null)
            return await next(cancellationToken);

        await _validator.HandleValidationAsync(request);
        return await next(cancellationToken);
    }
}

Si aucun validateur n'est enregistre pour le type de requete, le behavior passe directement au handler suivant. Sinon, la validation est executee et une exception est levee en cas d'echec.

EFCore

AppDbContextBase

Classe de base pour les DbContext des modules. Fournit les conventions communes.

IDataSeeder / ISeedManager

Interfaces pour le seeding des donnees initiales :

public interface IDataSeeder
{
    int Order { get; }
    Task SeedAllAsync();
}

Conventions

  • ToSnakeCaseTables() : conversion des noms de tables et colonnes en snake_case
  • FilterSoftDeletedProperties() : filtrage automatique des entites soft-deleted
  • ConvertEnumsToStrings() : stockage des enums en tant que strings dans la base
  • AddCustomDbContext<T>() : enregistrement standard d'un DbContext avec PostgreSQL
  • AddDatabaseMigration<T>() : migration automatique au demarrage avec ordonnancement

PostgresOptions

Options de configuration PostgreSQL (connection string).

Auditing

Infrastructure d'audit complete (detaillee dans la section Module Audit) :

ComposantDescription
AuditHttpMiddlewareAudit automatique de toutes les requetes HTTP
AuditCommandBehaviorAudit automatique de toutes les commandes MediatR
AuditEmitterEmission des evenements via MediatR notifications
AuditEventV1Structure d'un evenement d'audit
AuditMetricsMetriques OpenTelemetry
AuditMaskingServiceMasquage de donnees sensibles
AuditSeverityClassifierClassification de la severite
EntityChangeAuditSaveChangesInterceptorIntercepteur EF Core

BackgroundJobs

Integration Hangfire pour les taches de fond :

ComposantDescription
HangfireSettingsOptions de configuration Hangfire
HangfireStorageStartupTaskTache de demarrage pour la creation du storage
HangfireAdminDashboardAuthorizationFilterFiltre d'autorisation pour le dashboard
IMediatorBackgroundDispatcherInterface pour dispatcher des commandes MediatR en arriere-plan
MediatorBackgroundDispatcherImplementation via Hangfire
MediatorHangfireBridgeBridge entre Hangfire et MediatR
WhitelistSerializationBinderBinder de serialisation securise

Caching

Behaviors MediatR pour le cache :

ComposantDescription
ICacheRequestInterface marqueur pour les requetes cachees
IInvalidateCacheRequestInterface pour l'invalidation de cache
CachingBehaviorBehavior qui met en cache les resultats
InvalidateCachingBehaviorBehavior qui invalide le cache

Utilise EasyCaching (InMemory, Redis prevu).

Exception

Exceptions personnalisees avec typage fort :

ExceptionDescription
AppExceptionException de base de l'application
BadRequestExceptionRequete invalide (400)
NotFoundExceptionRessource non trouvee (404)
ConflictExceptionConflit (409)
InternalServerExceptionErreur serveur (500)
DomainExceptionException de domaine metier
AggregateNotFoundExceptionAggregat non trouve
CustomExceptionException personnalisee avec code d'erreur
ProblemDetailsWithCodeExtension de ProblemDetails avec un code d'erreur

Constants

TypeDescription
IdentityConstantConstantes partagees (noms de roles : Admin, User)

HealthCheck

TypeDescription
HealthOptionsOptions de configuration des health checks

OpenTelemetryCollector

TypeDescription
ActivityInfoInformations sur une activite OpenTelemetry
CreateActivityInfoCreation d'activites
ObservabilityConstantConstantes d'observabilite

PersistMessageProcessor

TypeDescription
MessageDeliveryTypeType de livraison de message (Internal, External)

Utils

TypeDescription
ServiceLocatorLocalisateur de service (anti-pattern, utilise avec parcimonie)