C# > Source Generators > Using Roslyn for Code Generation > Creating a Source Generator
Hello World Source Generator
This example demonstrates a basic source generator that adds a `HelloWorld` class with a `SayHello` method to the compilation. It's a minimal 'Hello, World!' for source generators.
Concepts Behind the Snippet
Source generators, introduced in C# 9, allow you to inspect user code and generate new C# source files that are added to the user's compilation. They operate during compilation, analyzing code to produce additional source code, which is then compiled alongside the original code. This avoids the runtime performance impact of reflection or code weaving techniques. This example showcases the basic structure of a source generator including the `Generator` attribute and the `Execute` method.
Implementation
This code defines a source generator named `HelloWorldGenerator`. The `Execute` method is the core of the generator. It creates a string containing the C# code for a `HelloWorld` class with a `SayHello` method. The `AddSource` method then adds this generated code to the compilation, effectively creating a new C# file named `HelloWorldGenerated.cs` during the build process. The `Initialize` method is intentionally left empty in this simple example, but it can be used for more complex generator setup.
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using System.Text;
namespace MySourceGenerator
{
[Generator]
public class HelloWorldGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
// Generate the source code
string sourceCode = $"""
namespace GeneratedCode
{{
public static class HelloWorld
{{
public static string SayHello()
{{
return \"Hello, World! This was generated.\";
}}
}}
}}
""";
// Add the source code to the compilation
context.AddSource("HelloWorldGenerated.cs", SourceText.From(sourceCode, Encoding.UTF8));
}
public void Initialize(GeneratorInitializationContext context)
{
// No initialization required for this example.
}
}
}
Real-Life Use Case
This simple example can be extended to generate code based on attributes, interfaces, or other information in the user's code. Imagine automatically generating boilerplate code for dependency injection, data access, or implementing interfaces. This reduces the amount of repetitive code developers need to write manually, improving maintainability and reducing errors. For example, you could create a source generator that automatically implements `INotifyPropertyChanged` based on attributes applied to properties.
Best Practices
Interview Tip
Be prepared to explain the benefits of source generators over traditional code generation techniques like T4 templates or runtime reflection. Highlight the compile-time nature, the performance benefits, and the improved developer experience.
When to Use Them
Source generators are ideal when you need to generate code based on existing code, attributes, or configurations at compile time. They are particularly useful for generating boilerplate code, implementing design patterns, or creating domain-specific languages (DSLs). Avoid using them for tasks that can be handled more efficiently with standard code or runtime mechanisms.
Memory Footprint
The memory footprint of a source generator itself is generally small. However, the generated code can increase the overall size of the compiled assembly. It is important to ensure that the generated code is optimized to minimize its impact on memory usage.
Alternatives
Alternatives to source generators include:
Pros
Cons
FAQ
-
How do I debug a source generator?
You can debug a source generator by attaching a debugger to the `msbuild.exe` process during the build. You can also use the `Debugger.Launch()` method in your source generator code to trigger the debugger. Ensure you have the necessary symbols loaded for your generator project. -
How do I reference external assemblies in a source generator?
You can reference external assemblies by adding them as analyzer dependencies in your project file. This allows your generator to access types and methods from those assemblies. -
Why isn't my source generator working?
Common reasons include:- The generator is not correctly registered in the project file.
- The generator is throwing an exception during execution. Check the build output for error messages.
- The generator is not being triggered because the required syntax or attributes are not present in the user's code.