CodegenCS
C# Toolkit for Code Generation (T4 alternative!)
Install / Use
/learn @Drizin/CodegenCSREADME
CodegenCS Toolkit
CodegenCS is a Code Generation Toolkit where templates are written using plain C#.
It can generate code in any language (like C#, Javascript, Python, HTML, JSX, Java, SQL Scripts, CSHTML or any other) or any other text-based output (YAML, XML, Markdown, Terraform files, Dockerfile, etc). It's very easy to learn even if you're not familiar with C# or Visual Studio.
It's a modern alternative to T4 Templates or generic templating engines like Razor/Liquid.
The major objective of the toolkit is to make code-generation as easy as possible by providing tools and helpers, abstracting boilerplate and letting you focus only in template logic.
"Simple things should be simple, and Complex things should be possible" (Alan Kay)
<br/><hr>
Major Features
Templates can be Markup-based or Programmatic
Our templates use a Hybrid model where they can be written programmatically or using a markup-language, and you can mix both approaches (switch between them at any moment). This provides the best balance between simplicity/maintenability and power (templates can be concise/maintenable and you can still have complex logic when needed).
- Programmatic approach is based on C# methods that explicitly write to output streams.
It provides more control and is the best choice when you have complex logic that would be too confusing to be written as markup. - Markup approach is based on text-blocks written using string interpolation, where literals can be mixed with interpolated objects (variables or subtemplates) or with simple control-flow markup (
if/else/endif, orloops).
It provides simplicity/readability and is the best choice when you need to write literals/variables with little logic or no logic.
It's similar to T4/Razor/Liquid/Handlebars but using pure C# and string interpolation - no need to learn a new syntax.
To sum our hybrid model provides the best of both worlds: you can write templates using your favorite language (C#), in your favorite IDE (Visual Studio) with full debugging capabilities - and you can leverage the power of .NET and any .NET library (think LINQ, Dapper, Newtonsoft, Swashbuckle, RestSharp, Humanizer, etc.)
Template Entrypoint
Templates are C# programs so they should have an entrypoint method (named Main() or TemplateMain()).
Methods (including entrypoint methods) can be "markup-based" os programmatic.
A markup-based method is one that just return an interpolated string:
class MyTemplate
{
FormattableString Main() => $"My first template";
}
A programmatic method can contain instructions and usually it writes explicitly to output streams:
class MyTemplate
{
void Main(ICodegenOutputFile writer)
{
writer.Write($"My first template");
}
}
Subtemplates (aka "partials")
In a programmatic method we obviously can just invoke other methods to break down a template into smaller (and more organized blocks), but when you have a markup-based block (i.e. a large string) it's not so obvious how you can include a "subtemplate":
In regular C# string interpolation we can only interpolate types that can be directly converted to string (string, FormattableString, int, DateTime, etc.), but in our magic TextWriter allows interpolating many other types including delegates (methods) so it's very easy to "embed" a subtemplate (a different method) right within an interpolated string.
In the example below template starts with a markup entry-point and then it "escapes" from the markup and switches to a programmatic subtemplate (another method that might have more complex logic):
class MyTemplate
{
string _ns = "MyNamespace";
FormattableString Main() => $$"""
namespace {{ _ns }}
{
{{ WriteClass }}
}
""";
void WriteClass(ICodegenOutputFile writer)
{
writer.WriteLine($$"""
public class MyFirstClass {
public void HelloWorld() {
// ...
}
}
""");
}
}
(WriteClass method will get the ICodegenOutputFile parameter automatically injected, as explained later).
Switching back and forth between programmatic-mode (C# methods) or markup mode (large C# strings) is what enables our hybrid model.
Indentation Control
Our clever Indent Control automatically captures the current indent (whatever number of spaces or tabs you have in current line) and will preserve it when you interpolate a large object (multiline) or when you interpolate a subtemplate.
Generating code with the correct indentation (even if there are multiple nested levels) has never been so easy, and it works for both curly-bracket languages (C#/Javascript/Java/Golang/etc) and also for indentation-based languages (like Python).
Explicit indent control is also supported.
Command-line Tool (dotnet-codegencs)
dotnet-codegencs is a cross-platform .NET tool (command-line tool).
It's available for Windows/Linux/MacOS.
Besides running templates, it can also be used to extract models from existing databases (reverse engineer db schema), or download our our sample templates. So if you want to quickly start generating code (e.g. based on your database) this is our "batteries-included" tool.
You can run it manually or you can automate into your build pipeline. See this example of a prebuild script that will install dotnet-codegencs, refresh a database schema, and run a template that generates POCOs.
Visual Studio Extension
Our Visual Studio Extension allows running templates directly from Visual Studio.
It's available for Visual Studio 2022 or Visual Studio 2019/2017.
Output files are automatically added to the project (nested under the template item), so it's easy to use (but it doesn't have all features available in dotnet-codegencs).
MSBuild Task
Our MSBuild Task (nuget here) allows running templates on-the-fly during compilation.
MSBuild Task CodegenBuildTask is automatically invoked during BeforeCompile target, will search for *.csx files in the project folder and will run each one.
Files are physically saved to disk and will be automatically added to your compilation (and obviously you can add that to .gitignore if you want).
Roslyn Source Generator
Our Source Generator (nuget here) allows running templates on-the-fly during compilation.
It's possible to render physical files on disk or just render in-memory (no need to add to source-control or put into ignore lists).
Important Classes
Before explaining more features it's important to first learn about 3 important classes:
1. CodegenTextWriter
CodegenTextWriter is the heart of CodegenCS toolkit.
We like to say it's a TextWriter on Steroids or a Magic TextWriter - but if you don't believe in magic you can say it's just a custom TextWriter that leverages string interpolation to automatically control indentation, and enriches string interpolation to allow interpolation of many types (like Action<> / Func<> delegates, IEnumerable<> lists) and special symbols (like IF/ELSE/ENDIF).
This enriched string interpolation is what allows pure C# string interpolation to be used as a markup-language.
CodegenTextWriter is just a text writer - it does not have any information about file path, and by default it writes to an in-memory StringBuilder (until output files are all saved at once).
Check out CodegenTextWriter documentation to learn more about it, about how indenting is magically controlled, learn how to write clean and reusable templates using String Interpolation, Raw String Literals, delegates and IEnumerables, and learn all object types can be interpolated.
2. CodegenOutputFile
Since CodegenTextWriter does not have any info about file paths, there is a subtype CodegenOutputFile which extends CodegenTextWriter by adding a relative path (where the file should be saved). Most tools use (I)CodegenOutputFile but actually the important logic is all in the base class CodegenTextWriter.
3. CodegenContext
CodegenContext is a container that can hold multiple instances of CodegenOutputFile (multiple output), and for simplicity it contains a default DefaultOutputFile.
When a template is executed it gets an empty context and it can write either to the default file or it can create multiple files.
Related Skills
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
96.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
