Source Generators ile Derleme Zamanı (Compile-time) Kod Üretimi
Source Generators ile Derleme Zamanı (Compile-time) Kod Üretimi
Konunun Mimari Önemi ve Temel Çalışma Prensipleri
Source Generators, .NET dil platformuyla birlikte gelen güçlü bir teknolojidir. Bu, geliştiricilerin derleme zamanında (compile-time) kod üretme imkanı sunar. Bu, metotları, sınıfları veya diğer kod öğelerini otomatik olarak oluşturarak verimliliği artırır, kod tekrarını azaltır ve hataları erken tespit edilmesini sağlar. Source Generators, özellikle genel amaçlı kod parçaları, otomatikleştirilmiş serialization, veri erişim katmanı kodları gibi senaryolarda oldukça faydalıdır.
Kurumsal Projelerde Dikkat Edilmesi Gereken En İyi Pratikler (Best Practices)
- Modüler ve Test Edilebilir Kod: Source Generators ile oluşturulan kodlar da modüler ve test edilebilir olmalıdır. Bu, kodun bakımını ve gelecekteki değişiklikleri yönetmek kolaylaştırır.
- Performans Dikkat Edilmesi: Source Generators, derleme süresini artırabilir. Bu nedenle, gereksiz veya fazla karmaşık kod üretimi kaçınılmalıdır.
- Belgelenmiş ve Dokumente Edilmiş: Source Generators tarafından üretilen kodlar, diğer geliştiriciler tarafından anlaşılabilir ve kullanılabilir olmalıdır. İyi belgeler ve dokumentasyon sağlar.
- Version Control: Source Generators tarafından üretilen kodlar, versiyon kontrol sistemlerine dahil edilmeli ve doğru şekilde yönetilmeli.
Gerçek Dünya Senaryolarına Uygun Kod Bloğu Örneği
Aşağıda, bir Source Generator kullanarak basit bir JSON serialization kodu üreten basit bir örnek bulunmaktadır. Bu örnek, verilen bir sınıf için JSON serialization kodunu derleme zamanında otomatik olarak üretir.
<!--#region Source Generator Code-->
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System.Linq;
namespace JsonSerializationGenerator
{
[Generator]
public class JsonSerializationSourceGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
// No initialization required for this example
}
public void Execute(GeneratorExecutionContext context)
{
foreach (var syntaxTree in context.Compilation.SyntaxTrees)
{
var root = syntaxTree.GetRoot();
var classDeclarations = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
foreach (var classDeclaration in classDeclarations)
{
var className = classDeclaration.Identifier.Text;
var namespaceName = syntaxTree.GetRoot().DescendantNodes().OfType<NamespaceDeclarationSyntax>().FirstOrDefault()?.Name.ToString();
var methodName = $"Serialize{className}";
var methodBody = GenerateMethodBody(className);
var method = SyntaxFactory.MethodDeclaration(
SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword)),
methodName)
.AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
.WithBody(SyntaxFactory.Block(
SyntaxFactory.ParseStatement($"var json = new System.Text.StringBuilder();"),
methodBody,
SyntaxFactory.ParseStatement($"return json.ToString();")
));
var newClassDeclaration = classDeclaration.AddMembers(method);
var updatedRoot = root.ReplaceNode(classDeclaration, newClassDeclaration);
context.AddSource($"{className}Serializer.g.cs", SourceText.From(updatedRoot.ToFullString(), Encoding.UTF8));
}
}
}
private SyntaxNode GenerateMethodBody(string className)
{
var properties = typeof(T).GetProperties();
var statements = new List<StatementSyntax>();
foreach (var property in properties)
{
statements.Add(SyntaxFactory.ParseStatement($"json.Append(@\"\\\"{property.Name}\\\": \");"));
statements.Add(SyntaxFactory.ParseStatement($"json.Append({property.Name}.ToString());"));
statements.Add(SyntaxFactory.ParseStatement($"json.Append(\", \");"));
}
statements.RemoveAt(statements.Count - 1); // Remove the last comma
return SyntaxFactory.Block(statements);
}
}
}
<!--#endregion-->
Performans Optimizasyonu ve Olası Darboğazlar
Source Generators, derleme süresini artırabilir. Bu nedenle, performans optimizasyonu için aşağıdaki stratejiler uygulanabilir:
- Minimum Kod Üretimi: Source Generators tarafından üretilen kod, sade ve verimli olmalıdır. Gereksiz kod parçaları ve yinelenen kodlar kaçınılmalıdır.
- Paralel İşleme: Source Generators, paralel olarak çalıştırılabilir. Bu, çoklu çekirdekli sistemlerde derleme süresini önemli ölçüde kısaltabilir.
- Kod Analizi ve Profil Oluşturma:





