CodeBlanks Logo Icon CodeBlanks

Summary - Source generators

C# course · Expert · Lesson 42/47

Combine IIncrementalGenerator and AddSource to write a DTO generator.

Summary - Source generators

In this summary you will write a DTO generator: from a list of type names it filters those ending in Dto, generates a class definition for each, and adds them to a list with AddSource. This simulates the core flow of a real source generator.

The methods from earlier lessons (Where, Select, AddSource and foreach) come together here. The output is deterministic because list order is preserved.

DTO generator design

The static DtoGenerator class holds a Sources list, an AddSource method, and a Generate method. Generate filters the type names and calls AddSource(name + ".g.cs", $"public class {name} {{ }}") for each.

Main calls Generate with three names; only those ending in Dto are added to the source list. Then foreach prints the hint names.

Exercise Assemble the DTO generator

Define a static class DtoGenerator. Give it public static List<(string Hint, string Source)> Sources { get; } = new();, public static void AddSource(string hintName, string source) (with Sources.Add((hintName, source));), and public static void Generate(IEnumerable<string> typeNames). In Generate, loop foreach (var name in typeNames.Where(n => n.EndsWith("Dto"))) and call AddSource(name + ".g.cs", $"public class {name} {{ }}"). In Main, call DtoGenerator.Generate(new[] { "User", "UserDto", "OrderDto" }) and print each entry.Hint with foreach.

Show example solution
static class DtoGenerator { public static List<(string Hint, string Source)> Sources { get; } = new(); public static void AddSource(string hintName, string source) { Sources.Add((hintName, source)); } public static void Generate(IEnumerable<string> typeNames) { foreach (var name in typeNames.Where(n => n.EndsWith("Dto"))) AddSource(name + ".g.cs", $"public class {name} {{ }}"); } }. In Main: DtoGenerator.Generate(...), foreach (var entry in DtoGenerator.Sources) Console.WriteLine(entry.Hint);
Example solution:
using System;
using System.Collections.Generic;
using System.Linq;

static class DtoGenerator
{
    public static List<(string Hint, string Source)> Sources { get; } = new();
    public static void AddSource(string hintName, string source)
    {
        Sources.Add((hintName, source));
    }
    public static void Generate(IEnumerable<string> typeNames)
    {
        foreach (var name in typeNames.Where(n => n.EndsWith("Dto")))
        {
            AddSource(name + ".g.cs", $"public class {name} {{ }}");
        }
    }
}

class Program
{
    static void Main()
    {
        DtoGenerator.Generate(new[] { "User", "UserDto", "OrderDto" });
        foreach (var entry in DtoGenerator.Sources)
        {
            Console.WriteLine(entry.Hint);
        }
    }
}

Test yourself

  1. Match each DTO generator step

    Where
    Filter names ending in Dto
    Select
    Generate a class definition
    AddSource
    Add generated code to the list
  2. What is the purpose of a source generator?

    • Do runtime reflection
    • Read files
    • Write tests
    • Generate code at compile time
    Show answer

    Generate code at compile time — Correct. A source generator generates code at compile time.

  3. Complete the Generate call

    DtoGenerator.____(new[] { "User", "UserDto", "OrderDto" });
    Show answer
    DtoGenerator.Generate(new[] { "User", "UserDto", "OrderDto" });

All lessons in Expert