A powerful and extensible template-based code generation framework for .NET. Features include Scriban template engine, template partials/includes, generation hooks, schema validation, configuration presets, batch generation, preview/diff, and fluent API.
$ dotnet add package CodeTemplateForgeA powerful and extensible template-based code generation framework for .NET.
Multiple Template Engines - Built-in Scriban support, extensible for others
Flexible Package Formats - Binary packages, directory-based, or custom formats
Customizable Magic Numbers - Define your own package format identifier
Value Processors - Built-in hex, bool-to-int, formatting, and more
Output Processors - Auto-formatting, line ending normalization
Event System - Progress tracking, logging, and cancellation support
Fluent API - Chain configuration calls for clean code
Generation Pipeline - Advanced pipeline with hooks and validation
Template Partials - Include/import support for template reuse
Schema Validation - JSON Schema-based context validation
Configuration Presets - Save and reuse configuration profiles
Batch Generation - Generate for multiple targets in parallel
Preview & Diff - Preview changes before writing files
Built-in Hooks - ZIP archive, manifest, README, clang-format
{{ variable_name }}
{{ if condition }}...{{ end }}
{{ for item in collection }}...{{ end }}
{{ variable | string.upcase }}
using TemplateForge;
using TemplateForge.Core;
// Create generator
var generator = new CodeGenerator();
// Load templates
await generator.LoadPackageAsync("templates.bin");
// Create context with variables
var context = new TemplateContext()
.Set("project_name", "MyProject")
.Set("version", "1.0.0")
.Set("author", "John Doe");
// Generate code
var result = await generator.GenerateAsync(context, outputPath);
// Using hex value
var generator = new CodeGenerator(0x4D595047); // "MYPG"
// Using string
var generator = new CodeGenerator("MYPG");
// Using helper
using TemplateForge.Utilities;
var magic = MagicNumberHelper.FromString("CHIP");
var generator = new CodeGenerator(magic);
using TemplateForge.Packaging;
// Build package programmatically
var builder = new TemplatePackageBuilder()
.WithId("my-templates")
.WithName("My Template Package")
.WithVersion("1.0.0")
.WithMagicNumber("MYPG") // Custom magic number
.AddTemplatesFromDirectory("./templates");
await builder.SaveAsync("my-templates.bin");
// Or quick pack
await PackageBuilderExtensions.PackDirectoryAsync(
"./templates",
"output.bin",
"*.template",
MagicNumberHelper.FromString("MYPG")
);
using TemplateForge.Extensions;
var context = new TemplateContext()
.SetHex("config_reg", 0x1A, 2) // "1a"
.SetBool("feature_enabled", true) // Sets 3 vars: feature_enabled, feature_enabled_int, is_feature_enabled
.SetDouble("timeout", 2.5) // Smart formatting
.SetEnum("mode", MyEnum.Option1); // Sets mode, mode_value, is_mode_option1, etc.
var generator = new CodeGenerator();
generator.ProgressChanged += (s, e) =>
Console.WriteLine($"[{e.ProgressPercentage:F0}%] {e.CurrentTemplate}");
generator.Log += (s, e) =>
Console.WriteLine($"[{e.Level}] {e.Message}");
generator.BeforeRendering += (s, e) =>
{
if (e.TemplateName.Contains("debug"))
e.Cancel = true; // Skip debug templates
};
generator.Completed += (s, e) =>
Console.WriteLine($"Done! {e.FilesGenerated} files in {e.Duration.TotalSeconds:F2}s");
var generator = new CodeGenerator()
.WithDefaults()
.WithDirectories("obj", "build")
.Configure(options =>
{
options.OverwriteExisting = true;
options.ContinueOnError = false;
options.ValidateTemplates = true;
options.OutputEncoding = Encoding.UTF8;
});
using TemplateForge;
using TemplateForge.Advanced;
using TemplateForge.Extensions;
var generator = new CodeGenerator();
await generator.LoadPackageAsync("templates.bin");
// Create pipeline with hooks
var pipeline = generator.CreatePipeline()
.WithCommonHooks() // Add logging and manifest
.WithCodeFormatting() // Add clang-format hook
.RegisterHook("CustomHook", HookTiming.AfterGeneration, ctx =>
{
Console.WriteLine($"Generated {ctx.GeneratedFiles.Count} files");
return HookResult.Ok();
});
// Execute pipeline
var result = await pipeline.ExecuteAsync(context, outputPath);
// Define a generic schema using builder
var pipeline = generator.CreatePipeline()
.WithSchema(schema => schema
.WithName("AppConfig")
.AddInteger("retry_count", required: true, min: 0, max: 10)
.AddDouble("timeout_seconds", required: true, min: 0.1, max: 300)
.AddBoolean("feature_enabled")
.AddEnum("log_level", new[] { "Debug", "Info", "Warn", "Error" }));
// Validation happens automatically before generation
var result = await pipeline.ExecuteAsync(context, outputPath);
// Register a preset
pipeline.Presets.Register(new ConfigurationPreset
{
Id = "staging",
Name = "Staging Defaults",
Variables = new Dictionary<string, object?>
{
["retry_count"] = 3,
["timeout_seconds"] = 30.0,
["feature_enabled"] = true,
["log_level"] = "Info"
}
});
// Apply preset to context
pipeline.Presets.ApplyPreset("staging", context);
var batchService = generator.CreateBatchService();
// Create targets for multiple variants
var targets = new BatchTargetBuilder()
.WithBaseContext(baseContext)
.AddTarget("Standard", ctx => ctx.Set("variant", "standard"))
.AddTarget("Pro", ctx => ctx.Set("variant", "pro"))
.AddCombinations("log_level", new[] { "Info", "Debug" })
.Build();
// Generate all targets
var result = await batchService.GenerateAsync(targets, outputPath, new BatchGenerationOptions
{
MaxParallelism = 4,
CreateSubdirectories = true
});
var pipeline = generator.CreatePipeline()
.WithPreview(async preview =>
{
Console.WriteLine(preview.GetSummary());
Console.WriteLine($"New files: {preview.NewFiles}");
Console.WriteLine($"Modified: {preview.ModifiedFiles}");
// Return true to proceed, false to cancel
return await ConfirmWithUser();
});
// Load partials from directory (files starting with _)
await pipeline.Partials.LoadFromDirectoryAsync("./templates/_partials");
// Or register manually
pipeline.Partials.Register("header", "/* Common header content */");
// Use in templates with include
// {{ include 'header' }}
TemplateForge/
├── Core/ # Template engine interfaces
├── Packaging/ # Package formats and loaders
├── Processing/ # Value and output processors
├── Configuration/ # Generator options
├── Extensions/ # Extension methods
├── Advanced/ # v2.0 Advanced features
│ ├── GenerationPipeline # Pipeline orchestration
│ ├── IGenerationHook # Hook system
│ ├── IContextValidator # Schema validation
│ ├── ConfigurationPreset # Preset management
│ ├── BatchGeneration # Multi-target generation
│ ├── GenerationPreview # Preview and diff
│ └── BuiltInHooks # Common hooks
├── Utilities/ # Helper classes
└── CodeGenerator.cs # Main entry point
MIT License