Regex und Logging mit Source Generators in .NET 6
- Matt
Mit .NET 6 kommen zwei Source Generators dazu, die man ohne eigenes Zutun nutzen kann: einer für reguläre Ausdrücke, einer für Logging. Beide erzeugen beim Übersetzen Code, den man sonst selbst schreiben oder zur Laufzeit bauen lassen müsste.
Regex Source Generators
Regex Source Generators ermöglichen es, reguläre Ausdrücke zur Kompilierzeit zu generieren und zu optimieren. Der Ausdruck wird damit beim Übersetzen in Code gegossen, statt beim ersten Aufruf zur Laufzeit gebaut zu werden.
Beispiel: Verwendung von Regex Source Generators
Um einen Regex Source Generator zu verwenden, muss die System.Text.RegularExpressions.Generators-Bibliothek eingebunden werden:
using System.Text.RegularExpressions;
[RegexGenerator(@"^\d{4}-\d{2}-\d{2}$")]
public partial class DateRegex : Regex
{
}
In diesem Beispiel wird ein Regex Source Generator verwendet, um einen regulären Ausdruck für das Format YYYY-MM-DD zu erstellen. Der Generator erstellt eine kompilierte Version des regulären Ausdrucks, die zur Laufzeit verwendet werden kann.
Vorteile
- Leistungssteigerung: Kompilierung zur Laufzeit entfällt, was die Ausführung beschleunigt.
- Kompilierungszeit-Fehler: Fehler im regulären Ausdruck werden bereits zur Kompilierungszeit erkannt.
Logging Source Generators
Logging Source Generators bieten eine effiziente Möglichkeit, Logging in .NET-Anwendungen zu implementieren. Sie ermöglichen die Erstellung von stark typisierten Logging-Methoden, die zur Laufzeit keine zusätzlichen Reflection-Kosten verursachen.
Beispiel: Verwendung von Logging Source Generators
Hier ist ein Beispiel, wie ein Logging Source Generator verwendet wird:
using Microsoft.Extensions.Logging;
public static partial class MyLoggerExtensions
{
[LoggerMessage(EventId = 0, Level = LogLevel.Information, Message = "Starting process {ProcessName}")]
public static partial void LogProcessStart(this ILogger logger, string processName);
}
public class MyService
{
private readonly ILogger<MyService> _logger;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
}
public void StartProcess(string processName)
{
_logger.LogProcessStart(processName);
}
}
In diesem Beispiel wird eine stark typisierte Logging-Methode LogProcessStart erstellt. Diese Methode wird vom Source Generator zur Kompilierzeit generiert und optimiert.
Vorteile
- Starke Typisierung: Verhindert Fehler bei der Angabe von Logging-Nachrichten und -Parametern.
- Keine Reflection-Kosten: Verbessert die Laufzeitleistung durch Vermeidung von Reflection.
Fazit
Beide Generatoren verschieben Arbeit von der Laufzeit in den Compiler. Der Regex-Generator spart das Übersetzen des Ausdrucks beim ersten Aufruf, der Logging-Generator die Formatierungskosten bei Meldungen, die am Ende gar nicht geschrieben werden.
Der Aufwand hält sich in Grenzen: In beiden Fällen steht am Ende ein partial-Methodenkopf mit Attribut statt eines Feldes oder eines Aufrufs.
Für weitere Details und eine ausführliche Anleitung besuche die offizielle Microsoft-Dokumentation.
Details zum Regex-Generator: Quellgenerierung für reguläre Ausdrücke.