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;
3
4[Generator]
5public class HelloGenerator: ISourceGenerator
6{
7public void Initialize(GeneratorInitializationContext context) { }
8
9public 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("}");
17
18context.AddSource("HelloWorld.g.cs", code.ToString());
19}
20}

Adım 3: Üretilen Kodu Kullanma

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası

Aynı çözümde bir Console uygulaması oluştur. MyGenerators projesine referans ekle. Şimdi yazabilirsin:

1using Generated;
2
3HelloWorld.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;
3
4[Generator]
5public class MapperGenerator: ISourceGenerator
6{
7public void Initialize(GeneratorInitializationContext context) { }
8
9public 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; } }");
22
23context.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, 30

Source 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.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz