Bonjour à tous,

Je travaille actuellement sur une application de gestion de contenus (type wiki) développée en .NET Core 9, avec un objectif microservices ready et une architecture suffisamment modulaire pour évoluer sans refonte lourde. L’application est prévue pour tourner sur Azure, sans conteneurs pour le moment.

Architecture simplifiée
Blazor (mode à définir : Auto, WASM ou Server ?) → API → Domaines → Shared

Détails des couches
  • Shared
    Contient toutes les abstractions et les contrats d’interface pour respecter DRY et SOLID, et éviter la duplication de définitions entre domaines.
  • Domaines
    Chaque domaine est organisé en plusieurs projets :
    • .csproj pour les services et repositories
    • .csproj pour le modèle
    • .csproj pour le data seeding (exécutable via PMC et YAML pipeline)


    Aujourd’hui, j’ai déjà un domaine pour la gestion des contenus (Content / ContentManagement).
    Je souhaite ajouter un domaine de gestion des comptes utilisateurs.
  • Seeders & DbContext
    Pour chaque domaine, j’ai mis en place un pattern avec IDesignTimeDbContextFactory pour permettre les migrations EF Core en toute sécurité, ainsi qu’un runner console pour exécuter les seeders (données réelles ou fictives).


Gestion des utilisateurs et sécurité
Mon idée est d’utiliser Microsoft Identity (ou son remplaçant le plus récent dans l’écosystème .NET).

  • Profiter de l’échafaudage automatique des pages] d’authentification/gestion utilisateurs (comme dans un projet Blazor avec Identity activé dès le départ).
  • Sécurité des APIs via JWT.
  • Objectif : isoler ce domaine comme pour les contenus, tout en gardant l’extensibilité nécessaire pour évoluer vers une architecture distribuée.


Questions ouvertes
  1. Validation architecture & microservices
    Est-ce que cette architecture vous semble bonne en l’état ?
    Si plus tard je déploie une API par domaine, cela sera-t-il conforme aux bonnes pratiques microservices ?
    Je cherche surtout des conseils pour rester DRY, SOLID et prêt pour des microservices.
  2. Gestion des comptes et sécurité backend
    J’hésite sur l’implantation : créer un domaine Account distribué par l’API pour gérer tout côté backend, ou utiliser la gestion intégrée à Blazor (Identity) et sécuriser les APIs via JWT.
    • Comment assurez-vous habituellement la sécurité, la gestion des utilisateurs et des rôles côté backend ?
    • Peut-on combiner l’implémentation Identity côté Blazor] avec la sécurisation des APIs ?
    • Je prévois aussi une section d’administration des comptes (avec admin), ce qui pousse vers un microservice dédié.

  3. Choix du modèle Blazor
    Entre Server, WASM et Auto, lequel est le plus pertinent dans un contexte “microservices ready” ?
    Je peine à comprendre les subtilités entre Server et WASM, et comment utiliser l’un ou l’autre pour sécuriser correctement mes APIs.


Extraits de code essentiels
Shared / Contracts / IRepository.cs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
public interface IRepository<TEntity> where TEntity : class
{
Task<TEntity?> GetByIdAsync(Guid id);
Task<IEnumerable<TEntity>> GetAllAsync();
Task AddAsync(TEntity entity);
void Update(TEntity entity);
void Remove(TEntity entity);
Task<int> SaveChangesAsync();
}
Shared / Data / BaseDbContext.cs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
public abstract class BaseDbContext : DbContext
{
public BaseDbContext(DbContextOptions options) : base(options) { }
}
Content / Data / ContentDbContext.cs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
public class ContentDbContext : BaseDbContext
{
public ContentDbContext(DbContextOptions<ContentDbContext> options) : base(options) { }
public DbSet<ContentItem> ContentItems => Set<ContentItem>();
}
Content / Data / DesignTimeContentDbContextFactory.cs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
public class DesignTimeContentDbContextFactory : IDesignTimeDbContextFactory<ContentDbContext>
{
public ContentDbContext CreateDbContext(string[] args)
{
var options = new DbContextOptionsBuilder<ContentDbContext>()
.UseSqlServer("DataSource=:memory:")
.Options;
return new ContentDbContext(options);
}
}
Seeders / ISeeder.cs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
public interface ISeeder
{
Task SeedAsync(CancellationToken cancellationToken = default);
string Name { get; }
}
Seeders / RealDataSeeder.cs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
public class RealDataSeeder : ISeeder
{
public async Task SeedAsync(CancellationToken cancellationToken = default)
{
// logique seeding réelle
}
}
Seeders / DummyDataSeeder.cs
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
public class DummyDataSeeder : ISeeder
{
public async Task SeedAsync(CancellationToken cancellationToken = default)
{
// logique seeding fictive
}
}
---

Merci d’avance pour vos retours et conseils 🙏