Source Generators: Compile-Time Code Üretimi ve Pratik Örnekler
Source Generators, C# 9 ile gelen bir özelliktir. Derleme sırasında (compile-time) yeni kod üretir; çalışma zamanında (runtime) değil. Bu sayede hız kazanır, yansıma (reflection) ihtiyacı azalır ve performans artar.
Niçin kullanalım? Seri hale getirme, DTO dönüştürme, dependency injection konfigürasyonu gibi tekrarlayan işlerde elle kod yazmak yerine generator otomatik olarak üretir. Hata riski düşer, bakım kolaylaşır.
Adım 1: Proje Kurulumu
Visual Studio'da yeni bir.NET 9 Class Library projesi oluştur. Buna "MyGenerators" diyebilirsin. Proje dosyasında (csproj) şu satırı ekle:
1<PropertyGroup>2<LangVersion>latest</LangVersion>3<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>4</PropertyGroup>Bu, üretilen dosyaları görmene izin verir.
Adım 2: Basit Bir Generator Yazma
Yeni bir sınıf oluştur, adı "HelloGenerator.cs":
1using Microsoft.CodeAnalysis;2using System.Text;34[Generator]5public class HelloGenerator: ISourceGenerator6{7public void Initialize(GeneratorInitializationContext context) { }89public void Execute(GeneratorExecutionContext context)10{11var code = new StringBuilder();12code.AppendLine("namespace Generated;");13code.AppendLine("public static class HelloWorld");14code.AppendLine("{");15code.AppendLine(" public static void Greet() => System.Console.WriteLine(\"Merhaba, ben üretildim!\");");16code.AppendLine("}");1718context.AddSource("HelloWorld.g.cs", code.ToString());19}20}Adım 3: Üretilen Kodu Kullanma
Aynı çözümde bir Console uygulaması oluştur. MyGenerators projesine referans ekle. Şimdi yazabilirsin:
1using Generated;23HelloWorld.Greet();Çıktı:
1Merhaba, ben üretildim!Pratik Örnek: Basit DTO Mapper
Daha yararlı bir örnek: bir sınıftan diğerine otomatik dönüştürme. "MapperGenerator.cs":
1using Microsoft.CodeAnalysis;2using System.Text;34[Generator]5public class MapperGenerator: ISourceGenerator6{7public void Initialize(GeneratorInitializationContext context) { }89public void Execute(GeneratorExecutionContext context)10{11var code = new StringBuilder();12code.AppendLine("namespace Generated;");13code.AppendLine("public class PersonMapper");14code.AppendLine("{");15code.AppendLine(" public static PersonDto Map(Person p)");16code.AppendLine(" {");17code.AppendLine(" return new PersonDto { Name = p.Name, Age = p.Age };");18code.AppendLine(" }");19code.AppendLine("}");20code.AppendLine("public class Person { public string Name { get; set; } public int Age { get; set; } }");21code.AppendLine("public class PersonDto { public string Name { get; set; } public int Age { get; set; } }");2223context.AddSource("PersonMapper.g.cs", code.ToString());24}25}Kullanım:
1var person = new Person { Name = "Ahmet", Age = 30 };2var dto = PersonMapper.Map(person);3Console.WriteLine($"{dto.Name}, {dto.Age}");Çıktı:
1Ahmet, 30Source Generators gerçek projede yansıma maliyetini ortadan kaldırır. Özellikle API serileştirme, ORM mapping ve konfigürasyon dosyaları için çok işe yarar.
0 yorum