# Source Generators

Source Generators are part of Roslyn feature that automatically generates code during the compilation process.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1702498751392/b4c9b294-3aa8-4628-b17d-b1a9c8c07c80.png align="center")

# Why Source Generators

* Alternatıve to Reflection
    
    * It is compile time not runtime
        
    * Unblock AOT trimming
        
    * It is just code
        

# Demo

The code produces the below output.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1702500267408/ee3d9bc1-e639-4ed3-a4cd-745d23ee5b24.png align="center")

```csharp
static void Main(string[] args)
{
    var classTypes = Assembly.GetEntryAssembly()
        .GetTypes()
        .Where(c => c.IsClass && c.IsPublic)
        .Select(c => c.FullName);

    foreach (var classType in classTypes)
    {
        Console.WriteLine(classType);
    }
}
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1702499933374/0397e76f-f302-4410-bcd7-762f8caac48a.png align="center")

## PublishAot

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1702500409738/4b7d87ab-cd85-4062-9dba-25e339f43700.png align="center")

If you have enabled PublishAot, it will publish to machine code and remove all unused references. Since our classes (Student, Course) are not reference, they will no be included in the published code and the output will be empty.

# Creating Source Generator

To use Source Generator, the project must target netstandard2.0. So, create a new class library with netstandard2.0.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1702500923738/f623020d-8970-4ff8-bae0-c958a93075b2.png align="center")

Add reference for the below packages.

```csharp
Microsoft.CodeAnalysis.Analyzers
Microsoft.CodeAnalysis.CSharp
```

Add the reference as below

```csharp
    <ProjectReference Include="..\Generator\Generator.csproj" OutputItemType="Analyzer" />
```

Make the changes in the Generator class.

```csharp
namespace Generator;

[Generator]
public class TheGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        var provider = context.SyntaxProvider.CreateSyntaxProvider(
            predicate: static(node, _) => node is ClassDeclarationSyntax,
            transform: static (ctx, _) => (ClassDeclarationSyntax)ctx.Node
            ).Where(c => c is not null);

        var compilation = context.CompilationProvider.Combine(provider.Collect());

        context.RegisterSourceOutput(compilation, Execute);
    }

    private void Execute(SourceProductionContext context, (Compilation Left, ImmutableArray<ClassDeclarationSyntax> Right) tuple)
    {
        var (compilation, list) = tuple;

        var namelist = new List<string>();

        foreach (var systax in list) {
            var symbol = compilation.GetSemanticModel(systax.SyntaxTree)
                .GetDeclaredSymbol(systax) as INamedTypeSymbol;

            namelist.Add($"\"{symbol.ToDisplayString()}\"");
        }

        var names = string.Join(",\n ", namelist);

        var theCode = $$"""
            namespace  Generator;

            public static class ClassNames {
                public static List<string> Names = new(){
                    {{ names }}
                };
            }
            """;

        context.AddSource("YourClassList.g.cs", theCode);
    }
}
```

## Reference

[https://www.youtube.com/watch?v=Yf8t7GqA6zA&list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&index=11](https://www.youtube.com/watch?v=Yf8t7GqA6zA&list=PLdo4fOcmZ0oULyHSPBx-tQzePOYlhvrAU&index=11)

[https://github.com/ibrahimuludag/sourcegenerator](https://github.com/ibrahimuludag/sourcegenerator)
