Depuis .NET 5, le compilateur Roslyn permet aux développeurs de générer du code pendant la compilation. Avec .NET 9, cette capacité devient plus mature et utile, notamment pour créer des outils qui suppriment la réflexion, injectent du code métier ou produisent des fichiers d’aide automatiquement. Voici un tour complet et concret du sujet.
🧠 Pourquoi utiliser un Source Generator ?
Contrairement à un T4 ou un template statique, un Source Generator :
- Est exécuté pendant la compilation (pas au runtime)
- Peut analyser le code du projet appelant
- Peut produire du code C# qui sera compilé automatiquement
Il est idéal pour :
- Supprimer des appels lents à la réflexion
- Générer des DTOs, wrappers, ou boilerplate
- Injecter du code en fonction d’annotations
⚙️ Créer un Source Generator minimal
- Créer un projet classlib dédié au générateur avec :
dotnet new classlib -n MyGenerator -f netstandard2.0
- Ajouter les packages nécessaires :
dotnet add package Microsoft.CodeAnalysis.CSharp --version 4.*
- Créer une classe comme suit :
[Generator]
public class HelloWorldGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context) { }
public void Execute(GeneratorExecutionContext context)
{
var sourceCode = @"
namespace Generated
{
public static class Hello
{
public static string SayHello() => \"Hello from generator!\";
}
}";
context.AddSource("Hello.g.cs", sourceCode);
}
}
Cela produira automatiquement une classe Generated.Hello accessible dans le projet cible.
🧪 Côté projet appelant : l’utiliser
Ajoutez une référence analyzers au projet :
<ItemGroup>
<ProjectReference Include="..\MyGenerator\MyGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
Et utilisez le code :
Console.WriteLine(Generated.Hello.SayHello());
✨ Exemple concret : générer un ToString() personnalisé
Avec une annotation maison :
[AutoToString]
public partial class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// Le générateur détecte cette classe et produit :
public partial class Person
{
public override string ToString() => $"Person(Name={Name}, Age={Age})";
}
Ainsi, le développeur gagne en lisibilité sans écrire de code inutile.
🔐 Limitations et bonnes pratiques
- Les Source Generators ne peuvent pas modifier du code existant
- Ils peuvent seulement ajouter du code
- Ne pas abuser : générer uniquement ce qui est utile à la compilation
- Utiliser SyntaxReceiver ou IncrementalGenerator pour des performances optimales
🚀 Bonus : vers les Incremental Generators
Depuis .NET 6+, il est recommandé d’utiliser l’interface IIncrementalGenerator, plus rapide et plus fine. Elle permet de découper l’analyse et la génération en pipelines bien contrôlés.
🔚 Conclusion
Les Source Generators changent la façon de concevoir certains outils C#. En supprimant de la réflexion ou du code répétitif, ils permettent d’obtenir des applications plus rapides et un code plus propre.
En .NET 9, c’est un levier puissant pour industrialiser une base de code tout en gagnant en confort.
Stay Tuned !