In this article, we are going to take a deep dive into C# source generators and how they can be used. We are then going to compare and contrast these generators against our very own C# generator that is currently available on the Codebots platform (a.k.a. C#Bot). As you will see, they both solve different problems and it is worthwhile knowing when to use each one and how they play nicely together.
Using C# source generators with C#Bot
The introduction of C# source generators was announced by Phillip in April 2020 and they looked pretty handy. During November 2020, C# 9 came out with support for code generators that included the implementation of source generators. So, let’s take a look at this brand new technology.
To begin, we are going to look into each of the following 3 questions:
- What are C# source generators?
- What is C#Bot?
- How would you use C# source generators with C#Bot?
But before we do so, we are going to briefly discuss reflection as you will need to understand this to use C# source generators. If you already know what reflection is, then skip straight to the next section. If you are unsure or need a little refresher, read on.
Reflective programming (or simply just reflection) is the ability for a program to inspect and manipulate its own structure at runtime. A simple example of reflection in C# is shown below. The output here is System.Int32.
// Using GetType to obtain type information:
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);
Even though this example is pretty basic a whole world opens up. Not only can you get the type, but you can discover everything about it, from its constructors, attributes, to its methods and pretty much everything.
Some of the most well known examples of how powerful reflection can be, are Object Relational Mapping (ORM) frameworks like the Entity framework or NHibernate. If you have never written a program using reflection, we highly recommend it. It is actually heaps of fun. But one last note on the use of reflection, there is a performance hit your program will take as the work is done in the runtime and compile time optimisations cannot be taken advantage of.
With that short intro to reflection, let’s now get on to the main course of this article.
What are C# source generators?
Source generators use reflection. In the description on the Roslyn GitHub site, they are described as using metaprogramming (see below). Metaprogramming and reflection are two terms for pretty much the same thing.
Source generators aim to enable compile time metaprogramming, that is, code that can be created at compile time and added to the compilation - Roslyn GitHub: Source Generators.
So, C# source generators are a new C# compiler feature. The source generator code runs during compilation and can inspect your program to produce additional files that are compiled together with the rest of your code. That’s cool!
The first thing you need to implement a source generator is a class implementing the ISourceGenerator interface with a Generator attribute.
[Generator]
public class CSVGenerator : ISourceGenerator
Then the Execute method is the entry point that is called by the compiler.
public void Execute(SourceGeneratorContext context) {
//Write some custom code here and add source code to the context
}
Luca’s C# source generator examples are a good starting point to look at some actual implementations but the best resource is the Cookbook found on the Roslyn GitHub site. There are many user scenarios listed, for example:
- As a generator author I want to be able to add a type to the compilation, that can be referenced by the user’s code
- As a generator author I want to be able to transform an external non-C# file into an equivalent C# representation
- As a generator author I want to be able to inspect and augment a user’s code with new functionality
- As a generator author I want to be able to add diagnostics to the users compilation
- As a generator author I want to be able to implement the INotifyPropertyChanged pattern automatically for a user
- As a generator author I want to package my generator as a NuGet package for consumption
- As a generator author I want to rely on functionality provided in NuGet packages inside my generator
- As a generator author I want to access the analyzer config properties for a syntax tree or additional file
- As a generator author I want to access key-value pairs that customize the generator output
- As a user of a generator I want to be able to customize the generated code and override defaults
- And many more!
Reading the list above it is clear that there are many use cases for when you might want to use source generators. But the important point is that source generators are available from C# 9 onwards as a compiler feature that allows you to use reflection (metaprogramming) to create more source code files to be used in the compilation. A very powerful concept indeed.
What is C#Bot?
Codebots are software robots that write code alongside developers. On average, they write about 93% of an application. Sometimes it is more, sometimes less. It depends on the requirements of the application.
C#Bot is one of the bots that are available on the Codebots platform. C#Bot writes a full-stack C# application using many familiar architectures and technologies to developers such as; REST, GraphQL, Docker, Entity Framework, MVC, and many more options.
The goal of any codebot is to write code that is understandable by a developer. Code generators are notorious for creating a code mess that no one can understand and turns into a black box. A codebot writes code that looks like a developer has written it, so developers can understand it, then refactor and change it to meet their specific requirements.
How would you use C# source generators with C#Bot?
C#Bot is accessed through the Codebots platform and depending on which product you are using, the code can be downloaded via a zip or you can also have C#Bot commit the code to a git repository.
1. Configure your options
The first step is to choose your tech stack with Codebots Studio. There are a lot of options available to you, but to get something simple you could consider switching off a lot of the options while you experiment.
2. Model your application
The next step is to model your application. To help you get a meaningful application quickly, you can use the templates found on the left-hand side of the Entity diagram. In the screenshot below, I have added the Fishing template.
3. Get your source code
After you build your app (button in the top right corner), you can follow the prompts to download your source code.
4. Add in a C# source generator
Now that you have your source code for the project you are ready to go ahead and add in a source generator!
If you downloaded the zip file via Codebots Studio, you can refactor the source code until your heart is content. There are no restrictions. It is your code.
You need to be careful where you put the code generated by the source generators. The bots expect that any developer written code inside a bot-written file is included in a protected region. So, if the source generator is creating a completely new class unknown to the bots, there is no problem. But if you are putting code inside a bot-written file, make sure it is in a protected region.
Summary
The introduction of C# source generators shows promise and it can be seen where they could be handy. At Codebots, being techies, we love to see more arrows in the quivers of software engineers to help solve problems. The source generators Cookbook has lots of use cases to consider.
As you have seen, C#Bot is in a different category of tools compared to C# source generators. C#Bot is accessed through a UI and writes (generates) a full-stack application. From there, developers have the control to do whatever they like with the code, like adding in some C# source generators. Source generators use reflection and metaprogramming to allow developers to add in extra code during compilation.
So, the perfect combination would be to use C#Bot to get a flying head start at the beginning of a project. This can shave days, weeks, and some times months of development time from your project. Then, once you have downloaded the source code via a zip file using Codebots Studio, there is nothing tying you back to the Codebots platform and you are free to customise and experiment with as many source generators as you need!