Waffle.Bakery
1.0.1
dotnet add package Waffle.Bakery --version 1.0.1
NuGet\Install-Package Waffle.Bakery -Version 1.0.1
<PackageReference Include="Waffle.Bakery" Version="1.0.1" />
<PackageVersion Include="Waffle.Bakery" Version="1.0.1" />
<PackageReference Include="Waffle.Bakery" />
paket add Waffle.Bakery --version 1.0.1
#r "nuget: Waffle.Bakery, 1.0.1"
#:package Waffle.Bakery@1.0.1
#addin nuget:?package=Waffle.Bakery&version=1.0.1
#tool nuget:?package=Waffle.Bakery&version=1.0.1
Waffle.Bakery
A batch-execution framework for running multiple Waffle templates and collecting their outputs. It handles the orchestration of template registration, execution, and result retrieval so you can focus on writing templates.
Quick Start
Add the NuGet packages to your project:
<ItemGroup>
<PackageReference Include="Waffle.Core" Version="1.x"/>
<PackageReference Include="Waffle.Bakery" Version="1.x"/>
</ItemGroup>
Define Templates
Create classes that inherit from DefaultTemplate. Each template declares a unique OutputId and implements
ProcessImpl:
using Waffle;
using static Waffle.WaffleSyntax;
public sealed class VectorTemplate : DefaultTemplate
{
protected override string OutputId => "vectors";
protected override void ProcessImpl(DefaultBakeryContext ctx)
{
const int N = 10;
Render(ctx, $"""
{For(2, N + 1, out var i)}
public readonly record struct Vector{i}(
{For(0, i, out var k, out var h)}
float Value{k + 1}{h.LastOrNot(");", ",")}
{End}
{End}
""");
}
}
public sealed class HelperTemplate : DefaultTemplate
{
protected override string OutputId => "helpers";
protected override void ProcessImpl(DefaultBakeryContext ctx)
{
const int N = 10;
Render(ctx, $$"""
public static class VectorMath
{
{{For(2, N + 1, out var i)}}
public static float Dot(in Vector{{i}} a, in Vector{{i}} b)
=> {{For(0, i, out var k, out var h):>>}}
a.Value{{k + 1}} * b.Value{{k + 1}}{{h.LastOrNot(";\n", " + "):>>}}
{{End}}
{{End}}
}
""");
}
}
Run the Bakery
Create a DefaultBakery, register templates, execute them, and retrieve results:
using Waffle;
var results = new DefaultBakery()
.Initialize(new DefaultBakeryContext())
.Register<VectorTemplate>()
.Register<HelperTemplate>()
.Run()
.GetResults();
// results is a Dictionary<string, string> keyed by OutputId
Console.WriteLine(results["vectors"]);
Console.WriteLine(results["helpers"]);
Architecture
Core Interfaces
| Interface | Role |
|---|---|
IBakery<T, TContext> |
Orchestrates template registration and batch execution. |
IBakeryContext |
Extends ITemplateInterpreterContext with named output destinations (Open/Close/Clear). |
ITemplate<TContext> |
Defines a single template's execution logic. |
Class Hierarchy
IBakery<T, TContext>
└── BakeryBase<T, TContext> # Shared registration/run logic
└── DefaultBakery # Ready-to-use concrete bakery
IBakeryContext
└── BakeryContextBase # Output buffering, error collection, lifecycle hooks
└── DefaultBakeryContext # No-op concrete context (sufficient for most use cases)
ITemplate<TContext>
└── SingleOutputTemplate<TContext> # Opens/closes a single OutputId automatically
└── DefaultTemplate # Shorthand for SingleOutputTemplate<DefaultBakeryContext>
Execution Flow
- Initialize —
bakery.Initialize(ctx)stores the context and callsOnConfigure. - Register — Templates are added to an internal list.
- Run — Iterates through registered templates and calls
Processon each. - Collect —
GetResults()returns aDictionary<string, string>mapping eachOutputIdto its rendered content.
Within each SingleOutputTemplate, Process automatically calls ctx.Open(OutputId) before your code and
ctx.Close() after, so you only need to implement ProcessImpl.
Template Registration
Manual registration
bakery.Register<MyTemplate>(); // instantiates via parameterless constructor
bakery.Register(new MyTemplate()); // pass a pre-built instance
Registration with a modifier
bakery.Register<MyTemplate>(t => t.SomeProperty = value);
Attribute-based auto-discovery
Scan an assembly for all template classes marked with a specific attribute:
bakery.RegisterAllByAttribute<GenerateAttribute>(typeof(Program).Assembly);
Optionally filter by attribute properties:
bakery.RegisterAllByAttribute<GenerateAttribute>(
typeof(Program).Assembly,
attr => attr.Enabled);
Customization
Custom Context
Subclass BakeryContextBase to add shared state, logging, or transformation hooks:
public class MyContext : BakeryContextBase
{
public string RootNamespace { get; set; } = "MyApp";
protected override void OnPostOpen(string outputId, bool isNew)
{
if (isNew) Console.WriteLine($"Generating: {outputId}");
}
}
Available hooks in BakeryContextBase:
| Hook | Timing |
|---|---|
OnPreOpen / OnPostOpen |
Before/after an output destination is opened |
OnPreAppend / OnPostAppend |
Before/after content is written |
OnPreClose / OnPostClose |
Before/after an output destination is closed |
OnPreAppendLiteral / OnPostAppendLiteral |
Before/after a literal string segment is appended |
OnPreAppendFormatted / OnPostAppendFormatted |
Before/after an interpolated expression is appended |
OnCleared |
After all output is discarded |
Custom Bakery
Subclass BakeryBase<T, TContext> to add project-specific orchestration:
public class MyBakery : BakeryBase<MyBakery, MyContext>
{
protected override void OnConfigure(MyContext ctx)
{
// Called once during Initialize — set up shared resources here
}
}
Template Lifecycle Hooks
SingleOutputTemplate<TContext> provides OnPreProcess and OnPostProcess hooks:
public abstract class MyTemplateBase : SingleOutputTemplate<MyContext>
{
protected override void OnPreProcess(MyContext ctx)
{
// e.g., emit a file header
Render(ctx, $"// Auto-generated — do not edit\n");
}
}
Error Handling
If ProcessImpl throws an exception, SingleOutputTemplate catches it and records a TemplateError on the context.
After execution, retrieve errors with:
var errors = bakery.GetErrors(); // Dictionary<string, IReadOnlyList<TemplateError>>
foreach (var (outputId, errs) in errors)
{
foreach (var e in errs)
Console.Error.WriteLine($"[{outputId}] {e.Message}");
}
Dependencies
| Product | Versions 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. |
-
.NETStandard 2.0
- Waffle.Core (>= 1.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.