Moquestra.CodeWriter 2.0.0

dotnet add package Moquestra.CodeWriter --version 2.0.0
                    
NuGet\Install-Package Moquestra.CodeWriter -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Moquestra.CodeWriter" Version="2.0.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Moquestra.CodeWriter" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Moquestra.CodeWriter">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Moquestra.CodeWriter --version 2.0.0
                    
#r "nuget: Moquestra.CodeWriter, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Moquestra.CodeWriter@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Moquestra.CodeWriter&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Moquestra.CodeWriter&version=2.0.0
                    
Install as a Cake Tool

Moquestra.CodeWriter

Build and test NuGet

Source-only text writer for code generation.

CodeBuilder accumulates interpolated strings. Literal text is written as-is, and a multiline interpolated value is reindented from its second line with the prefix of the line where the interpolation begins - so a template stays readable while the generated code keeps its indentation.

var body = "a();\nb();";
var builder = new CodeBuilder();

builder.WriteLine($"void M()");
builder.WriteLine($"{{");
builder.WriteLine($"    {body}");
builder.WriteLine($"}}");
void M()
{
    a();
    b();
}

With C# 11 raw string literals the same template reads like the code it produces - no escaped braces, no \n:

builder.Write($$"""
    void M()
    {
        {{body}}
    }
    """);

The prefix is copied verbatim by default, which also works for comment templates:

var summary = "First line.\nSecond line.";

builder.Write($"/// {summary}");
/// First line.
/// Second line.

Installation

NuGet

dotnet add package Moquestra.CodeWriter

The package ships C# source files instead of an assembly. They compile into your project as internal types, so every consuming assembly gets its own copy and different versions never collide. The package is a development dependency: dotnet add package writes PrivateAssets="all" for you, and the reference does not flow to consumers of your own package.

Copying the sources

Projects that do not use NuGet can copy the sources from a clone of this repository with one of the scripts in the root:

# PowerShell
./copy-source.ps1 -Destination <folder>

# sh
./copy-source.sh <folder>

# cmd
copy-source.bat <folder>

Each script copies the source files verbatim into the folder.

Sharing a copy between assemblies

The types are internal, so a copy is visible only inside the assembly it was compiled into. To let other assemblies use the same copy, add this to any C# file in the assembly that holds it:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("FriendAssembly")]

Usage

Writing

  • Write(FormattableString) renders the interpolated string and accumulates it.
  • WriteLine() ends the current line; WriteLine(FormattableString) writes and ends the line.
  • ToString() returns everything accumulated so far.

Values that implement IFormattable are rendered with the invariant culture; other values fall back to ToString(), and null renders as an empty string. A CodeBuilder can be interpolated into another builder, so fragments compose.

To repeat a template for a sequence of items, render each fragment with its own CodeBuilder, join the results, and interpolate the joined text. A fragment built as a plain interpolated string never passes through a builder, so multiline values inside it are not reindented.

An interpolation hole holds a plain expression. Format and alignment components inside a hole - {value:X}, {value,-10} - are not supported and throw FormatException.

Continuation prefixes

Each line of a multiline value after the first receives a continuation prefix derived from the line where the interpolation began. PreservedPrefixParts selects which characters of that line are kept verbatim; the rest are each replaced with a space.

Value Prefix "\t- " becomes
All (default) "\t- "
Tabs "\t "
NonWhitespace " - "
None " "

An empty line, or a line emptied by trimming, keeps the prefix without its trailing whitespace - so /// continues while indentation does not.

Write(FormattableString, PreservedPrefixParts) overrides the selection for one call.

Whitespace-only lines

A line that ends holding nothing but spaces and tabs is emptied, whether the whitespace came from literal text or from a value (TrimWhitespaceOnlyLines, on by default). The check runs when the line ends, so text appended to an open line is unaffected.

Settings

CodeBuilderSettings is immutable and groups the output options:

var settings = new CodeBuilderSettings(
    newLine: "\r\n",               // "\n" (default) or "\r\n"
    trimWhitespaceOnlyLines: true, // default
    prefixParts: PreservedPrefixParts.All);

var builder = new CodeBuilder(settings);

Input line endings - CRLF, CR and LF - are normalized to the configured newline, in literals and in interpolated values alike.

XML documentation comments

XmlDoc assembles the lines of an XML documentation comment. Tags render in call order, and ToString() joins the lines with LF and no comment prefix, so the prefix comes from the template:

var doc = new XmlDoc()
    .Summary("Gets the value.")
    .Param("id", "The ID to look up.")
    .Returns("The value, or null when the ID is unknown.");

builder.Write($"/// {doc}");
/// <summary>Gets the value.</summary>
/// <param name="id">The ID to look up.</param>
/// <returns>The value, or null when the ID is unknown.</returns>

Ten tags are available: Summary, Remarks, Returns, Value, Example, Param, TypeParam, Exception, InheritDoc and SeeAlso. Text is written as-is, so inline markup such as <c> and <see cref="..."/> can be embedded; XmlDoc.Escape escapes a value that must appear literally. Attribute values - names and cref references - are always escaped.

A text-bearing tag renders inline when its text is a single line and as a block - opening tag, text lines, closing tag - when it spans several lines. Pass an XmlDocForm to the constructor to change the default for the document, or to a tag method to change it for one call:

var doc = new XmlDoc(XmlDocForm.Block)
    .Summary("Gets the value.")
    .Param("id", "The ID to look up.", XmlDocForm.Inline);
<summary>
Gets the value.
</summary>
<param name="id">The ID to look up.</param>

Requirements

The sources compile with C# 7.3 or later and use only APIs available in .NET Standard 2.0, so they can be added to any project whose target framework supports .NET Standard 2.0. They contain no nullable annotations and compile without warnings whether nullable reference types are enabled or disabled.

Unity

Use one of the copy scripts to place the sources in the folder of the assembly definition that will use them - usually an Editor assembly - and share the copy with other assemblies as described above if needed. NuGetForUnity can install the package too, but it puts the files under Assets/Packages without an assembly definition, so they compile into Assembly-CSharp, which assembly-definition based code cannot reference.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 114 9/14/2026
1.0.0 146 9/2/2026