Enterprise C# : comment écrire du code dont on n'a pas honte lors d'une revue de code

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Enterprise C# : pourquoi le code pour une banque et le code pour un projet personnel sont deux univers différents

\n\n

Si vous êtes déjà passé d'une petite agence web à une grande entreprise ou une fintech, vous connaissez ce sentiment de léger choc culturel. Hier, vous pouviez commiter un « correctif urgent » sans tests et avec un seul commentaire //TODO: refactor, et aujourd'hui vous recevez une revue avec 20 remarques, où chaque méthode publique nécessite une documentation XML, et chaque dépendance doit être enregistrée dans un conteneur DI.

\n\n

Le développement C# en entreprise ne consiste pas à « faire vite », mais à « faire en sorte que ça ne casse pas dans trois ans, quand l'auteur du code aura été licencié ». Il s'agit de prévisibilité, de mise à l'échelle et de revues de code interminables. Voyons ce qui compose réellement le développement C# en entreprise et comment ne pas être viré dès la première semaine.

\n\n

1. Architecture : SOLID n'est pas un mot à la mode, c'est une loi

\n\n

Dans une startup, vous pouvez vous permettre un monolithe avec des chaînes « magiques » et des classes géantes de 2000 lignes. En entreprise, non. Ici, chaque principe SOLID n'est pas une abstraction, mais un guide d'action.

\n\n

Principe de responsabilité unique (SRP)

\n

Votre classe ne doit pas savoir comment envoyer des e-mails, sauvegarder dans la base de données et analyser du XML en même temps. Si vous voyez trois responsabilités ou plus dans une seule classe, c'est une odeur. En entreprise, un tel code sera refusé lors de la revue avec la mention « violation du SRP, à réécrire ». Exemple de mauvais code :

\n\n
public class OrderService\n{\n    public void ProcessOrder(Order order)\n    {\n        // 1. Validation\n        // 2. Sauvegarde en BDD\n        // 3. Envoi d'e-mail\n        // 4. Journalisation\n    }\n}
\n\n

La bonne approche consiste à diviser en services séparés et à utiliser le pattern Mediator ou Pipeline :

\n\n
public class ProcessOrderCommandHandler : IRequestHandler<ProcessOrderCommand, bool>\n{\n    private readonly IOrderRepository _repo;\n    private readonly IEmailService _email;\n    private readonly ILogger<ProcessOrderCommandHandler> _logger;\n\n    public ProcessOrderCommandHandler(IOrderRepository repo, IEmailService email, ILogger<ProcessOrderCommandHandler> logger)\n    {\n        _repo = repo;\n        _email = email;\n        _logger = logger;\n    }\n\n    public async Task<bool> Handle(ProcessOrderCommand request, CancellationToken cancellationToken)\n    {\n        var order = await _repo.GetByIdAsync(request.OrderId);\n        // logique\n        await _email.SendAsync(order.CustomerEmail, "Order processed");\n        _logger.LogInformation("Order {Id} processed", order.Id);\n        return true;\n    }\n}
\n\n

Remarquez : chaque service fait exactement une chose. Tester un tel code est beaucoup plus simple.

\n\n

2. Dependency Injection — votre meilleur ami

\n\n

Dans les projets d'entreprise en C#, vous ne verrez presque jamais new MyService() à l'intérieur d'une classe. À la place, on utilise un conteneur DI (généralement Autofac ou le Microsoft.Extensions.DependencyInjection intégré).

\n\n

La règle est simple : si une classe crée elle-même ses dépendances, elle viole le Principe d'inversion des dépendances. En entreprise, cela est considéré comme une erreur d'architecture. Exemple :

\n\n
// ❌ Mauvais : couplage fort\npublic class ReportGenerator\n{\n    private readonly PdfExporter _exporter = new PdfExporter();\n    public byte[] Generate() => _exporter.Export();\n}\n\n// ✅ Bon : inversion des dépendances\npublic class ReportGenerator\n{\n    private readonly IExporter _exporter;\n    public ReportGenerator(IExporter exporter) => _exporter = exporter;\n    public byte[] Generate() => _exporter.Export();\n}
\n\n

Enregistrement dans le démarrage :

\n
services.AddScoped<IExporter, PdfExporter>();\nservices.AddScoped<ReportGenerator>();
\n\n

Pourquoi est-ce nécessaire ? Premièrement, pour les tests : vous pouvez simuler IExporter et ne pas gén

Blogs

Book Recommendations