ConsoleForge.SourceGen 0.3.0

dotnet add package ConsoleForge.SourceGen --version 0.3.0
                    
NuGet\Install-Package ConsoleForge.SourceGen -Version 0.3.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="ConsoleForge.SourceGen" Version="0.3.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="ConsoleForge.SourceGen" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="ConsoleForge.SourceGen">
  <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 ConsoleForge.SourceGen --version 0.3.0
                    
#r "nuget: ConsoleForge.SourceGen, 0.3.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 ConsoleForge.SourceGen@0.3.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=ConsoleForge.SourceGen&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=ConsoleForge.SourceGen&version=0.3.0
                    
Install as a Cake Tool

ConsoleForge.SourceGen {#sourcegen}

Roslyn source generator for ConsoleForge. Eliminates Update(IMsg) dispatch boilerplate from your models and components.

Installation

dotnet add package ConsoleForge
dotnet add package ConsoleForge.SourceGen

Note: This is a development dependency — it runs at compile time and produces no runtime overhead.

[DispatchUpdate] — Auto-generated Update dispatch

Instead of writing the Update switch by hand:

public (IModel Model, ICmd? Cmd) Update(IMsg msg) => msg switch
{
    NavUpMsg   => OnNavUp(),
    NavDownMsg => OnNavDown(),
    SelectMsg  => OnSelect(),
    _          => (this, null),
};

Mark the type partial and add [DispatchUpdate]:

[DispatchUpdate]
sealed partial record ListPage(int Index = 0) : IComponent
{
    static readonly KeyMap Keys = new KeyMap()
        .On(ConsoleKey.UpArrow,   () => new NavUpMsg())
        .On(ConsoleKey.DownArrow, () => new NavDownMsg())
        .On(ConsoleKey.Enter,     () => new SelectMsg());

    public ICmd? Init() => null;
    public IWidget View() => new ConsoleForge.Widgets.List(Items, Index);

    // Generator finds On{X} methods → emits Update() with a switch
    (IModel, ICmd?) OnNavUp()   => (this with { Index = Index - 1 }, null);
    (IModel, ICmd?) OnNavDown() => (this with { Index = Index + 1 }, null);
    (IModel, ICmd?) OnSelect()  => (this with { Result = Items[Index] }, null);
}

The generator:

  1. Finds all methods matching (IModel, ICmd?) On{X}(...)
  2. Looks for a corresponding {X}Msg type in scope
  3. Emits the Update(IMsg) switch with one arm per handler
  4. Detects a static KeyMap Keys field → emits Keys.Handle(msg) pre-dispatch
  5. Default arm returns (this, null)

Handler conventions

Pattern Generated switch arm
(IModel, ICmd?) OnFoo() FooMsg => OnFoo(),
(IModel, ICmd?) OnFoo(FooMsg msg) FooMsg __m => OnFoo((FooMsg)__m),

[Component] — Scaffold boilerplate

When combined with [DispatchUpdate] (or used alone), [Component] generates:

  • IComponent<T>.Result explicit interface implementation (reads from your Result property)
  • public ICmd? Init() => null; (when not already declared)
[DispatchUpdate, Component]
sealed partial record FilePicker(string? Result = null) : IComponent<string>
{
    public IWidget View() => ...;

    (IModel, ICmd?) OnPick(PickMsg msg) => (this with { Result = msg.Path }, null);
    (IModel, ICmd?) OnCancel()          => (this, null);
}

// Generated:
// - string IComponent<string>.Result => Result!;
// - public ICmd? Init() => null;
// - public (IModel, ICmd?) Update(IMsg msg) => msg switch { ... };

Diagnostics

Code Severity Description
CFG001 Error Type must be declared partial to use [DispatchUpdate]
CFG002 Warning Handler skipped — message type not found or duplicate handler
CFG003 Warning Handler return type must be (IModel, ICmd?)
CFG004 Info Type already declares Update(IMsg) — generator skips dispatch

Requirements

  • ConsoleForge ≥ 0.2.0 (provides the trigger attributes)
  • .NET SDK ≥ 8.0
  • No runtime dependency — the generator runs at compile time only

License

MIT — see LICENSE.

There are no supported framework assets in this 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
0.3.0 98 4/21/2026
0.2.2 97 4/20/2026
0.2.1 99 4/17/2026

v.0.2.2: Small changes to EquatableArray class

       v0.2.1: Initial release — [DispatchUpdate] and [Component] attribute support, source generator implementation plan.