Introduction
editMeziantou.Framework.CodeDom builds C# source code from objects instead of strings. You create a tree of code objects (a compilation unit, its namespaces, types, members, statements and expressions) and the library writes the C# code, with the indentation, the braces, the parentheses and the escaping done for you:
var unit = new CompilationUnit();
unit.AddUsing("System");
var ns = unit.AddNamespace("Demo");
var type = ns.AddType(new ClassDeclaration("Greeter")
{
Modifiers = Modifiers.Public,
});
var method = type.AddMember(new MethodDeclaration("GetMessage")
{
Modifiers = Modifiers.Public | Modifiers.Static,
ReturnType = typeof(string),
});
var nameArgument = method.AddArgument("name", typeof(string));
method.Statements = new ReturnStatement(Expression.Add("Hello ", nameArgument, "!"));
var generatedCode = unit.ToCsharpString();generatedCode contains:
using System;
namespace Demo
{
public class Greeter
{
public static string GetMessage(string name)
{
return (("Hello " + name) + "!");
}
}
}It is a modern replacement for System.CodeDom, which has not evolved for years, focused on C#: records, nullable reference types, async and await, nameof, generic constraints such as unmanaged...
Use it in code generators, scaffolding tools, source generators or build tasks that write C# files: the code is easier to compose and to refactor than string concatenation, and the output is always well formed.
Principles
- A tree of objects. Every element is a CodeObject with a Parent. Adding an object to a collection or assigning it to a property attaches it to the tree.
- Conversions keep the code short. A
Type, astring, a number, aboolor an enum converts to the matching type reference or literal, and a member declaration or an argument to a reference to it. - The output is explicit. Binary expressions are parenthesized, and the types that are not C# keywords are written with their full name and
global::, so the meaning of the generated code does not depend on operator precedence or on theusingdirectives of the file. - No compilation. The library writes source code; it does not check that the code compiles.
Next steps
- Getting started: install the package and generate a file.
- Declarations: namespaces, types, members and attributes.
- Statements and expressions: the code inside members.