-
Notifications
You must be signed in to change notification settings - Fork 0
feat(docs): add AGENTS.md iterative development cycle #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,259 @@ | ||||||||||||||||||
| # BrilliantMediator — Prompt de démarrage projet | ||||||||||||||||||
|
|
||||||||||||||||||
| > Ce fichier est la source de vérité pour tout agent IA (Claude, GitHub Copilot, OpenCode). | ||||||||||||||||||
| > Lis-le intégralement avant toute action. Le silence n'est pas une validation. | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Contexte produit | ||||||||||||||||||
|
|
||||||||||||||||||
| **BrilliantMediator** est une bibliothèque .NET ultra-légère implémentant le pattern Mediator. | ||||||||||||||||||
|
|
||||||||||||||||||
| Caractéristiques fondamentales : | ||||||||||||||||||
| - **Zéro réflexion** — résolution par génériques compilés, pas de `typeof` à l'exécution | ||||||||||||||||||
| - **Performances** — overhead < 50 ns par opération, comparable à un appel direct | ||||||||||||||||||
| - **CQRS** — Commands (avec/sans réponse), Queries, Events (fire-and-forget parallèle) | ||||||||||||||||||
| - **DI-first** — intégration native avec `Microsoft.Extensions.DependencyInjection` | ||||||||||||||||||
| - **Source Generator** — enregistrement automatique des handlers via `BrilliantMediator.SourceGenerator` | ||||||||||||||||||
|
|
||||||||||||||||||
| Stack : .NET 10 — C# — xUnit — NuGet (`BrilliantMediator`) | ||||||||||||||||||
|
|
||||||||||||||||||
| Namespace racine : `Monbsoft.BrilliantMediator` | ||||||||||||||||||
|
|
||||||||||||||||||
| --- | ||||||||||||||||||
|
|
||||||||||||||||||
| ## Structure du projet | ||||||||||||||||||
|
|
||||||||||||||||||
| ``` | ||||||||||||||||||
| src/ | ||||||||||||||||||
| ├── BrilliantMediator/ | ||||||||||||||||||
| │ ├── Abstractions/ | ||||||||||||||||||
| │ │ ├── Commands/ ICommand, ICommand<TResponse>, ICommandHandler<T>, ICommandHandler<T,R> | ||||||||||||||||||
| │ │ ├── Queries/ IQuery<TResponse>, IQueryHandler<TQuery,TResponse> | ||||||||||||||||||
| │ │ ├── Events/ IEvent, IEventHandler<TEvent> | ||||||||||||||||||
| │ │ └── IMediator.cs | ||||||||||||||||||
| │ ├── Core/ | ||||||||||||||||||
| │ │ ├── Mediator.cs Implémentation principale (ConcurrentDictionary, scoped DI) | ||||||||||||||||||
| │ │ ├── MediatorOptions.cs | ||||||||||||||||||
| │ │ └── MediatorDiagnosticEvent.cs | ||||||||||||||||||
| │ ├── Extensions/ | ||||||||||||||||||
| │ │ ├── BrilliantMediatorExtensions.cs AddBrilliantMediator(IServiceCollection) | ||||||||||||||||||
| │ │ └── MediatorBuilder.cs | ||||||||||||||||||
| │ └── Exceptions/ | ||||||||||||||||||
| │ └── HandlerNotRegisteredException.cs | ||||||||||||||||||
| │ | ||||||||||||||||||
| └── BrilliantMediator.SourceGenerator/ Roslyn Source Generator | ||||||||||||||||||
|
|
||||||||||||||||||
| tests/ | ||||||||||||||||||
| └── BrilliantMediator.Tests/ | ||||||||||||||||||
|
|
||||||||||||||||||
| samples/ | ||||||||||||||||||
| ├── ConsoleApp/ | ||||||||||||||||||
| └── EcommerceDDD/ | ||||||||||||||||||
|
|
||||||||||||||||||
| docs/ | ||||||||||||||||||
| ├── spec.md Source de vérité architecture + ADR | ||||||||||||||||||
| ├── GUIDE.md | ||||||||||||||||||
| ├── EXAMPLES.md | ||||||||||||||||||
| └── CHANGELOG.md | ||||||||||||||||||
|
Comment on lines
+55
to
+58
|
||||||||||||||||||
| ├── spec.md Source de vérité architecture + ADR | |
| ├── GUIDE.md | |
| ├── EXAMPLES.md | |
| └── CHANGELOG.md | |
| ├── GUIDE.md | |
| ├── EXAMPLES.md | |
| ├── CHANGELOG.md | |
| └── NuGetReadme.md |
Copilot
AI
Mar 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cette section impose de documenter les décisions dans docs/spec.md, mais ce fichier n’existe pas actuellement. Pour éviter des références mortes, soit créer docs/spec.md, soit pointer vers le fichier réellement utilisé pour les ADR (ou indiquer explicitement qu’il est à créer).
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,134 @@ | ||
| # BrilliantMediator — Spec & Architecture | ||
|
|
||
| > Source de vérité du projet. Mise à jour à la fin de chaque itération. | ||
| > Dernière mise à jour : 2026-03-20 — itération #1 (AGENTS.md) | ||
|
|
||
| --- | ||
|
|
||
| ## Vision produit | ||
|
|
||
| BrilliantMediator est une bibliothèque .NET ultra-légère implémentant le pattern Mediator sans réflexion runtime. | ||
| Elle cible les développeurs qui veulent les bénéfices du CQRS (séparation Commands / Queries / Events) | ||
| sans la surcharge de performance ni la complexité des bibliothèques existantes. | ||
|
|
||
| **Proposition de valeur :** zéro réflexion, overhead < 50 ns, API type-safe au compile-time. | ||
|
|
||
| --- | ||
|
|
||
| ## API publique — v1.2.0 | ||
|
|
||
| ### IMediator | ||
|
|
||
| ```csharp | ||
| // Commands | ||
| Task DispatchAsync<TCommand>(TCommand command) where TCommand : ICommand; | ||
| Task<TResponse> DispatchAsync<TCommand, TResponse>(TCommand command) where TCommand : ICommand<TResponse>; | ||
|
|
||
| // Queries | ||
| Task<TResponse> SendAsync<TQuery, TResponse>(TQuery query) where TQuery : IQuery<TResponse>; | ||
|
|
||
| // Events | ||
| Task PublishAsync<TEvent>(TEvent @event) where TEvent : IEvent; | ||
|
|
||
| // Registration (DI type) | ||
| void RegisterCommandHandler<TCommand>() where TCommand : ICommand; | ||
| void RegisterCommandHandler<TCommand, TResponse>() where TCommand : ICommand<TResponse>; | ||
| void RegisterQueryHandler<TQuery, TResponse>() where TQuery : IQuery<TResponse>; | ||
| void RegisterEventHandler<TEvent>() where TEvent : IEvent; | ||
|
|
||
| // Registration (instance — tests) | ||
| void RegisterCommandHandler<TCommand>(ICommandHandler<TCommand> handler); | ||
| void RegisterCommandHandler<TCommand, TResponse>(ICommandHandler<TCommand, TResponse> handler); | ||
| void RegisterQueryHandler<TQuery, TResponse>(IQueryHandler<TQuery, TResponse> handler); | ||
| void RegisterEventHandler<TEvent>(IEventHandler<TEvent> handler); | ||
| ``` | ||
|
|
||
| ### Abstractions | ||
|
|
||
| | Interface | Rôle | | ||
| |-----------|------| | ||
| | `ICommand` | Commande sans réponse | | ||
| | `ICommand<TResponse>` | Commande avec réponse | | ||
| | `ICommandHandler<TCommand>` | Handler de commande sans réponse | | ||
| | `ICommandHandler<TCommand, TResponse>` | Handler de commande avec réponse | | ||
| | `IQuery<TResponse>` | Requête | | ||
| | `IQueryHandler<TQuery, TResponse>` | Handler de requête | | ||
| | `IEvent` | Événement domaine | | ||
| | `IEventHandler<TEvent>` | Handler d'événement (multi-handler supporté) | | ||
|
|
||
| ### Configuration DI | ||
|
|
||
| ```csharp | ||
| services.AddBrilliantMediator(assembly); | ||
| // ou | ||
| services.AddBrilliantMediator(builder => builder.AddHandlersFromAssembly(assembly)); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Fonctionnalités livrées | ||
|
|
||
| | Version | Fonctionnalité | Date | | ||
| |---------|---------------|------| | ||
| | 1.0.0-beta.1 | Commands (avec/sans réponse) + Queries — architecture zéro réflexion | 2025-11-04 | | ||
| | 1.0.0-beta.2 | Events (PublishAsync parallèle) + DI Extension + MediatorBuilder | 2025-11-05 | | ||
| | 1.0.0 | Version stable. Exemple EcommerceDDD | 2024-11-06 | | ||
| | 1.1.0 | Scoping DI renforcé par handler d'événement | 2025-11-09 | | ||
| | 1.2.0 | Migration .NET 10 | 2026-03-20 | | ||
|
|
||
| --- | ||
|
|
||
| ## Itérations en cours / planifiées | ||
|
|
||
| | # | Sujet | Statut | | ||
| |---|-------|--------| | ||
| | 1 | AGENTS.md — cycle de développement itératif | Livré (PR #8) | | ||
| | 2 | Réduction verbosité API (génériques) | En discussion | | ||
|
|
||
| --- | ||
|
|
||
| ## ADR (Architecture Decision Records) | ||
|
|
||
| ### ADR-001 — Zéro réflexion via ConcurrentDictionary + génériques compilés | ||
|
|
||
| - **Contexte :** Les implémentations Mediator courantes (MediatR) utilisent la réflexion pour résoudre les handlers à l'exécution, ajoutant un overhead significatif. | ||
| - **Décision :** Utiliser `ConcurrentDictionary<string, Type>` avec des clés générées statiquement à partir des noms complets de types. Résolution via DI standard sans `ActivatorUtilities`. | ||
| - **Conséquences :** Overhead < 50 ns. Enregistrement explicite requis (ou via Source Generator). Pas de découverte automatique "magique". | ||
|
|
||
| ### ADR-002 — Scope DI par appel dans DispatchAsync / SendAsync / PublishAsync | ||
|
|
||
| - **Contexte :** Les handlers peuvent dépendre de services scoped (ex. `DbContext` EF Core). Un singleton partagé provoquerait des corruptions de données. | ||
| - **Décision :** Chaque appel crée son propre `IServiceScope` via `_serviceProvider.CreateScope()`. Pour les events : chaque handler obtient son propre scope indépendant. | ||
| - **Conséquences :** Isolation garantie. Légère surcharge de création de scope (< 1 µs, négligeable). | ||
|
|
||
| ### ADR-003 — Enregistrement explicite des handlers (Register*) | ||
|
|
||
| - **Contexte :** La découverte automatique par réflexion viole le principe zéro réflexion. | ||
| - **Décision :** Enregistrement explicite via `RegisterCommandHandler<T>()` ou via `MediatorBuilder.AddHandlersFromAssembly()` (scan assemblies au démarrage uniquement, pas à l'exécution). | ||
| - **Conséquences :** Verbosité accrue vs. MediatR. Contrepartie : erreurs détectées au démarrage, pas à l'exécution. | ||
|
|
||
| --- | ||
|
|
||
| ## Dette technique | ||
|
|
||
| - `PublishAsync` utilise un `lock` sur `List<Type>` lors de la copie des handlers — pourrait être remplacé par `ImmutableList<T>` pour éliminer le lock dans le chemin chaud. | ||
| - Les handlers d'instances dans `RegisterCommandHandler(handler)` ne stockent que le type — l'instance n'est pas utilisée lors du dispatch DI (comportement potentiellement surprenant en tests). | ||
| - `docs/CHANGELOG.md` section `[Unreleased]` liste des fonctionnalités non implémentées (diagnostics, middlewares, CancellationToken, i18n) — à nettoyer ou à créer des issues. | ||
|
|
||
| --- | ||
|
|
||
| ## Prochaine itération | ||
|
|
||
| **#2 — Réduction verbosité API publique** | ||
|
|
||
| Objectif : réduire les paramètres de type redondants dans les appels `DispatchAsync` et `SendAsync`. | ||
|
|
||
| ```csharp | ||
| // Actuel — TResponse doit être répété | ||
| var result = await mediator.DispatchAsync<CreateOrderCommand, OrderId>(command); | ||
|
|
||
| // Cible envisagée — TResponse inféré depuis ICommand<TResponse> | ||
| var result = await mediator.DispatchAsync(command); | ||
| ``` | ||
|
|
||
| > Statut : en discussion — clarification besoin/périmètre/contraintes en cours. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Le document affirme l’existence d’un projet
BrilliantMediator.SourceGeneratoret d’un "Source Generator" associé, mais il n’y a aucun projet/dossier correspondant dans le repo actuel (aucun matchSourceGeneratorsoussrc/). Soit ajouter le projet, soit retirer/adapter ces mentions pour que ce fichier reste une source de vérité.