Les analyseurs Roslyn permettent d’ajouter des règles de validation personnalisées lors de la compilation. Cela peut s’avérer particulièrement utile pour faire respecter des conventions métier, éviter des pièges récurrents ou guider les développeurs d’une équipe.
Dans cet article, nous allons créer un analyseur simple qui interdit l’appel direct à DateTime.Now, en forçant l’usage d’un service d’abstraction du temps.
🛠️ Prérequis
- Visual Studio 2022+ avec le workload « Développement .NET »
- SDK .NET 9+
- Modèle de projet « Analyseur de code C# » (VSIX ou bibliothèque classique)
🧱 Étape 1 – Créer le projet d’analyseur
- Nouveau projet > Rechercher « analyseur »
- Choisir Bibliothèque d’analyseurs C#
- Nommer : NoDateTimeNowAnalyzer
Cela génère deux projets :
- NoDateTimeNowAnalyzer : l’analyseur lui-même
- NoDateTimeNowAnalyzer.Test : les tests unitaires avec xUnit + infrastructure Roslyn
🧩 Étape 2 – Écrire une règle d’analyse
Dans NoDateTimeNowAnalyzer.cs :
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class NoDateTimeNowAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "NODATENOW";
private static DiagnosticDescriptor Rule = new(
DiagnosticId,
"Éviter DateTime.Now",
"L'appel à DateTime.Now est interdit : utilisez IClock",
"Conventions métier",
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Rule];
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.SimpleMemberAccessExpression);
}
private void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var memberAccess = (MemberAccessExpressionSyntax)context.Node;
if (memberAccess.ToString() == "DateTime.Now")
{
var diagnostic = Diagnostic.Create(Rule, memberAccess.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
}
🧪 Étape 3 – Tester l’analyseur
Dans le projet de test généré :
[Fact]
public async Task DateTimeNow_ProvoqueAlerte()
{
var code = """
class TestClass {
void Test() {
var t = DateTime.Now;
}
}
""";
var expected = Verify.Diagnostic("NODATENOW").WithSpan(4, 26, 4, 40);
await Verify.VerifyAnalyzerAsync(code, expected);
}
Utilisez VerifyCS de Microsoft.CodeAnalysis.CSharp.Testing.XUnit pour simplifier les tests.
🧪 Étape 4 – Intégration dans un projet réel
Référencez le projet ou package NuGet généré par votre analyseur dans un projet de production. Le warning apparaîtra automatiquement dans l’IDE et à la compilation.
✅ Conclusion
Créer un analyseur Roslyn permet de personnaliser les règles de compilation pour faire respecter vos standards internes, notamment métier. Cet exemple peut être adapté pour interdire d'autres usages ou guider les développeurs vers de meilleures pratiques.
Stay Tuned !