Ever wanted to type less for the most common things you type over and over? Oh yes, me too. Probably would shave off 6-months lost time over the years.
- Create 2 projects:
- Console App:
Sample.ConsoleApp
- Standard Library:
Learn.SourceGenerator
- Console App:
- Add NuGet packages to the Standard Lib project,
Microsoft.CodeAnalysis.Analyzers
andMicrosoft.CodeAnalysis.CSharp
.
- In the console app, change the class type from
internal class
topartial class
. - Next, add our method we're going to generate
namespace Sample.ConsoleApp;
// Refactor fron `internal class` to `partial class`
partial class Program
{
static partial void HelloFrom(string name);
static void Main(string[] args)
{
HelloFrom("my generated method Code");
}
}
- Reference the source generator library
- Modify the Console App's csproj file
<!-- Add this as a new ItemGroup, replacing paths and names appropriately -->
<ItemGroup>
<ProjectReference Include="..\PathTo\SourceGenerator.csproj"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false" />
</ItemGroup>
using Microsoft.CodeAnalysis;
namespace Learn.SourceGenerator
{
[Generator]
public class HelloGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
// Code generation goes here
// Find the main method
var mainMethod = context.Compilation.GetEntryPoint(context.CancellationToken);
// Build up the source code
string source = $@" // Auto-generated code
using System;
namespace {mainMethod.ContainingNamespace.ToDisplayString()}
{{
public static partial class {mainMethod.ContainingType.Name}
{{
static partial void HelloFrom(string name) =>
Console.WriteLine($""Generator says: Hi from '{{name}}'"");
}}
}}
";
var typeName = mainMethod.ContainingType.Name;
// Add the source code to the compilation
context.AddSource($"{typeName}.g.cs", source);
}
public void Initialize(GeneratorInitializationContext context)
{
// No initialization required for this one
}
}
}