Blazor pour SOLID : retour d'expérience

Découvrez comment Blazor facilite l'application des principes SOLID dans vos applications web. Retour d'expérience concret sur l'amélioration de la maintenabilité et de la qualité du code, avec exe...

Olivier Dupuy
05 août 2025

5

Vues

0

Commentaires

3

Min de lecture

Dans le monde du développement .NET moderne, l'application des principes SOLID est devenue incontournable pour créer des applications maintenables et évolutives. Blazor, le framework web de Microsoft, ne fait pas exception à cette règle. À travers cet article, je partage mon retour d'expérience sur l'implémentation des principes SOLID dans une application Blazor, en mettant en lumière les défis rencontrés et les solutions adoptées.

Les principes SOLID dans le contexte Blazor

Avant de plonger dans l'implémentation, rappelons brièvement les principes SOLID et leur pertinence dans Blazor :

  • Single Responsibility Principle (SRP) : Chaque composant Blazor ne doit avoir qu'une seule raison de changer
  • Open/Closed Principle (OCP) : Les composants doivent être ouverts à l'extension mais fermés à la modification
  • Liskov Substitution Principle (LSP) : Les composants dérivés doivent pouvoir remplacer leurs composants de base
  • Interface Segregation Principle (ISP) : Les interfaces doivent être spécifiques aux besoins des clients
  • Dependency Injection Principle (DIP) : Les dépendances doivent s'appuyer sur des abstractions

Implémentation pratique

Single Responsibility Principle

Voici un exemple de composant Blazor respectant le SRP :


// UserProfileComponent.razor
@inject IUserService UserService
@inject ILogger Logger

@if (User != null) {

}

@code { [Parameter] public string UserId { get; set; }

private UserModel User { get; set; }

protected override async Task OnInitializedAsync() { try { User = await UserService.GetUserAsync(UserId); } catch (Exception ex) { Logger.LogError(ex, "Error loading user profile"); } } }

Open/Closed Principle

Pour respecter l'OCP, nous pouvons créer des composants extensibles :


// IDataDisplayComponent.cs
public interface IDataDisplayComponent
{
    T Data { get; set; }
    RenderFragment CustomTemplate { get; set; }
}

// GenericDataDisplay.razor @typeparam T @implements IDataDisplayComponent

@if (Data != null) { @if (CustomTemplate != null) { @CustomTemplate } else {

@DefaultTemplate(Data)
} }

@code { [Parameter] public T Data { get; set; }

[Parameter] public RenderFragment CustomTemplate { get; set; }

private RenderFragment DefaultTemplate => (data) => @@data.ToString(); }

Dependency Injection et Services

L'utilisation correcte de l'injection de dépendances est cruciale dans Blazor :


// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped();
    services.AddScoped();
    services.AddScoped();
}

// UserService.cs public class UserService : IUserService { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger;

public UserService( IHttpClientFactory httpClientFactory, ILogger logger) { _httpClientFactory = httpClientFactory; _logger = logger; }

public async Task GetUserAsync(string userId) { try { var client = _httpClientFactory.CreateClient("API"); return await client.GetFromJsonAsync($"api/users/{userId}"); } catch (Exception ex) { _logger.LogError(ex, "Error fetching user data"); throw; } } }

Patterns d'implémentation courants

Mediator Pattern

Le pattern Mediator s'intègre particulièrement bien avec Blazor et les principes SOLID :


// MediatorService.cs
public class MediatorService : IMediatorService
{
    private readonly IServiceProvider _serviceProvider;

public MediatorService(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; }

public async Task SendAsync(IRequest request) { var handlerType = typeof(IRequestHandler<,>).MakeGenericType(request.GetType(), typeof(TResponse)); var handler = _serviceProvider.GetService(handlerType); if (handler == null) throw new InvalidOperationException($"Handler not found for {request.GetType()}");

return await (Task)handlerType .GetMethod("Handle") .Invoke(handler, new object[] { request }); } }

Tests et validation

Les tests unitaires sont essentiels pour valider l'implémentation des principes SOLID :


// UserProfileComponentTests.cs
public class UserProfileComponentTests
{
    [Fact]
    public async Task Should_Load_User_Profile_Successfully()
    {
        // Arrange
        var mockUserService = new Mock();
        mockUserService
            .Setup(x => x.GetUserAsync(It.IsAny()))
            .ReturnsAsync(new UserModel { Id = "1", Name = "Test User" });

var cut = new UserProfileComponent { UserId = "1" };

// Act await cut.OnInitializedAsync();

// Assert Assert.NotNull(cut.User); Assert.Equal("Test User", cut.User.Name); } }

Considérations de performance

L'application des principes SOLID ne doit pas se faire au détriment des performances :

  • Utiliser le lazy loading pour les composants lourds
  • Implémenter une stratégie de cache efficace
  • Optimiser les rendus avec ShouldRender()


// LazyLoadedComponent.razor
@if (shouldRender)
{
    
@ChildContent
}

@code { private bool shouldRender;

[Parameter] public RenderFragment ChildContent { get; set; }

protected override bool ShouldRender() => shouldRender;

public void Show() { shouldRender = true; StateHasChanged(); } }

Conclusion

L'application des principes SOLID dans Blazor nécessite une réflexion approfondie mais apporte des bénéfices significatifs en termes de maintenabilité et d'évolutivité. Les points clés à retenir sont :

  • La séparation claire des responsabilités entre composants
  • L'utilisation efficace de l'injection de dépendances
  • La création de composants extensibles et réutilisables
  • L'importance des tests unitaires
  • L'équilibre entre principes SOLID et performances

En suivant ces principes et en utilisant les patterns appropriés, vous pourrez créer des applications Blazor robustes et maintenables sur le long terme.

Partager cet article
42
12

Commentaires (0)

Rejoignez la discussion

Connectez-vous pour partager votre avis et échanger avec la communauté

Première discussion

Soyez le premier à partager votre avis sur cet article !

À propos de l'auteur
Olivier Dupuy

Développeur passionné et contributeur actif de la communauté technique.

Profil
Navigation rapide
Commentaires (0)