diff --git a/README.md b/README.md index c5aaacf27..cc165afcf 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# RSCG - 253 Examples of Roslyn Source Code Generators / 16 created by Microsoft / +# RSCG - 254 Examples of Roslyn Source Code Generators / 16 created by Microsoft / -The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 253 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. +The RSCG_Examples repository is a comprehensive documentation system that automatically processes and showcases 254 Roslyn Source Code Generator (RSCG) examples. The system transforms individual RSCG projects into structured documentation with code examples and cross-referenced content with a searchable website and code example exports. This system serves as both a learning resource for .NET developers interested in source generators and an automated pipeline for maintaining up-to-date documentation about the RSCG ecosystem -## Latest Update : 2026-02-01 => 01 February 2026 +## Latest Update : 2026-02-02 => 02 February 2026 If you want to see examples with code, please click ***[List V2](https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG)*** @@ -24,8 +24,30 @@ If you want to be notified each time I add a new RSCG example , please click htt ## Content -Those are the 253 Roslyn Source Code Generators that I have tested you can see and download source code example. +Those are the 254 Roslyn Source Code Generators that I have tested you can see and download source code example. ( including 16 from Microsoft ) +### 254. [ErrorOrX](https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX) , in the [API](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#api) category + +Generated on : 2026-02-02 => 02 February 2026 + +
+ Expand + + + +Author: Alexander Nachtmanns + +A discriminated union type for .NET with source-generated ASP.NET Core Minimal API integration. Zero boilerplate, full AOT support. + +Nuget: [https://www.nuget.org/packages/ErrorOrX/](https://www.nuget.org/packages/ErrorOrX/) + + +Link: [https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX](https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX) + +Source: [https://github.com/ANcpLua/ErrorOrX](https://github.com/ANcpLua/ErrorOrX) + +
+ ### 253. [FastCloner](https://ignatandrei.github.io/RSCG_Examples/v2/docs/FastCloner) , in the [Clone](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#clone) category Generated on : 2026-02-01 => 01 February 2026 @@ -5897,483 +5919,476 @@ Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/AlexNav73/CoreCraft&body=https://github.com/AlexNav73/CoreCraft -19) [https://github.com/ANcpLua/ErrorOrX]( https://github.com/ANcpLua/ErrorOrX) , https://github.com/ANcpLua/ErrorOrX - -Why I have not tested : later - -https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/ANcpLua/ErrorOrX&body=https://github.com/ANcpLua/ErrorOrX - - -20) [https://github.com/atc-net/atc-source-generators]( https://github.com/atc-net/atc-source-generators) , https://github.com/atc-net/atc-source-generators +19) [https://github.com/atc-net/atc-source-generators]( https://github.com/atc-net/atc-source-generators) , https://github.com/atc-net/atc-source-generators Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/atc-net/atc-source-generators&body=https://github.com/atc-net/atc-source-generators -21) [https://github.com/Atoen/TextLocalizer]( https://github.com/Atoen/TextLocalizer) , https://github.com/Atoen/TextLocalizer +20) [https://github.com/Atoen/TextLocalizer]( https://github.com/Atoen/TextLocalizer) , https://github.com/Atoen/TextLocalizer Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/Atoen/TextLocalizer&body=https://github.com/Atoen/TextLocalizer -22) [https://github.com/Aymen83/AspectWeaver]( https://github.com/Aymen83/AspectWeaver) , https://github.com/Aymen83/AspectWeaver +21) [https://github.com/Aymen83/AspectWeaver]( https://github.com/Aymen83/AspectWeaver) , https://github.com/Aymen83/AspectWeaver Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/Aymen83/AspectWeaver&body=https://github.com/Aymen83/AspectWeaver -23) [https://github.com/bjornhellander/TestInheritanceGenerator]( https://github.com/bjornhellander/TestInheritanceGenerator) , https://github.com/bjornhellander/TestInheritanceGenerator +22) [https://github.com/bjornhellander/TestInheritanceGenerator]( https://github.com/bjornhellander/TestInheritanceGenerator) , https://github.com/bjornhellander/TestInheritanceGenerator Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/bjornhellander/TestInheritanceGenerator&body=https://github.com/bjornhellander/TestInheritanceGenerator -24) [https://github.com/borisdj/CsCodeGenerator]( https://github.com/borisdj/CsCodeGenerator) , https://github.com/borisdj/CsCodeGenerator +23) [https://github.com/borisdj/CsCodeGenerator]( https://github.com/borisdj/CsCodeGenerator) , https://github.com/borisdj/CsCodeGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/borisdj/CsCodeGenerator&body=https://github.com/borisdj/CsCodeGenerator -25) [https://github.com/buchmiet/FastFsm]( https://github.com/buchmiet/FastFsm) , https://github.com/buchmiet/FastFsm +24) [https://github.com/buchmiet/FastFsm]( https://github.com/buchmiet/FastFsm) , https://github.com/buchmiet/FastFsm Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/buchmiet/FastFsm&body=https://github.com/buchmiet/FastFsm -26) [https://github.com/chickensoft-games/LogicBlocks]( https://github.com/chickensoft-games/LogicBlocks) , https://github.com/chickensoft-games/LogicBlocks +25) [https://github.com/chickensoft-games/LogicBlocks]( https://github.com/chickensoft-games/LogicBlocks) , https://github.com/chickensoft-games/LogicBlocks Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/chickensoft-games/LogicBlocks&body=https://github.com/chickensoft-games/LogicBlocks -27) [https://github.com/dgmjr-io/InterfaceGenerator]( https://github.com/dgmjr-io/InterfaceGenerator) , https://github.com/dgmjr-io/InterfaceGenerator +26) [https://github.com/dgmjr-io/InterfaceGenerator]( https://github.com/dgmjr-io/InterfaceGenerator) , https://github.com/dgmjr-io/InterfaceGenerator Why I have not tested : issue opened https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/dgmjr-io/InterfaceGenerator&body=https://github.com/dgmjr-io/InterfaceGenerator -28) [https://github.com/eddievelasquez/IntercodeToolbox]( https://github.com/eddievelasquez/IntercodeToolbox) , https://github.com/eddievelasquez/IntercodeToolbox +27) [https://github.com/eddievelasquez/IntercodeToolbox]( https://github.com/eddievelasquez/IntercodeToolbox) , https://github.com/eddievelasquez/IntercodeToolbox Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/eddievelasquez/IntercodeToolbox&body=https://github.com/eddievelasquez/IntercodeToolbox -29) [https://github.com/FoundatioFx/Foundatio.Mediator]( https://github.com/FoundatioFx/Foundatio.Mediator) , https://github.com/FoundatioFx/Foundatio.Mediator +28) [https://github.com/FoundatioFx/Foundatio.Mediator]( https://github.com/FoundatioFx/Foundatio.Mediator) , https://github.com/FoundatioFx/Foundatio.Mediator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/FoundatioFx/Foundatio.Mediator&body=https://github.com/FoundatioFx/Foundatio.Mediator -30) [https://github.com/GaoNian-NET/MapperToolkit]( https://github.com/GaoNian-NET/MapperToolkit) , https://github.com/GaoNian-NET/MapperToolkit +29) [https://github.com/GaoNian-NET/MapperToolkit]( https://github.com/GaoNian-NET/MapperToolkit) , https://github.com/GaoNian-NET/MapperToolkit Why I have not tested : issue opened https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/GaoNian-NET/MapperToolkit&body=https://github.com/GaoNian-NET/MapperToolkit -31) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/ +30) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/ Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/IeuanWalker/MinimalApi.Endpoints/&body=https://github.com/IeuanWalker/MinimalApi.Endpoints/ -32) [https://github.com/inputfalken/Dynatello]( https://github.com/inputfalken/Dynatello) , https://github.com/inputfalken/Dynatello +31) [https://github.com/inputfalken/Dynatello]( https://github.com/inputfalken/Dynatello) , https://github.com/inputfalken/Dynatello Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/inputfalken/Dynatello&body=https://github.com/inputfalken/Dynatello -33) [https://github.com/ionite34/MinimalApiMapper]( https://github.com/ionite34/MinimalApiMapper) , https://github.com/ionite34/MinimalApiMapper +32) [https://github.com/ionite34/MinimalApiMapper]( https://github.com/ionite34/MinimalApiMapper) , https://github.com/ionite34/MinimalApiMapper Why I have not tested : own idea where to generate files, so overwrites https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/ionite34/MinimalApiMapper&body=https://github.com/ionite34/MinimalApiMapper -34) [https://github.com/JasonBock/CslaGeneratorSerialization]( https://github.com/JasonBock/CslaGeneratorSerialization) , https://github.com/JasonBock/CslaGeneratorSerialization +33) [https://github.com/JasonBock/CslaGeneratorSerialization]( https://github.com/JasonBock/CslaGeneratorSerialization) , https://github.com/JasonBock/CslaGeneratorSerialization Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/JasonBock/CslaGeneratorSerialization&body=https://github.com/JasonBock/CslaGeneratorSerialization -35) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface +34) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/MoslemBenDhaou/DataSurface&body=https://github.com/MoslemBenDhaou/DataSurface -36) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate +35) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/mu-dawood/EasyValidate&body=https://github.com/mu-dawood/EasyValidate -37) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp +36) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/nuskey8/Csv-CSharp&body=https://github.com/nuskey8/Csv-CSharp -38) [https://github.com/OrgEleCho/EleCho.Internationalization]( https://github.com/OrgEleCho/EleCho.Internationalization) , https://github.com/OrgEleCho/EleCho.Internationalization +37) [https://github.com/OrgEleCho/EleCho.Internationalization]( https://github.com/OrgEleCho/EleCho.Internationalization) , https://github.com/OrgEleCho/EleCho.Internationalization Why I have not tested : issue opened https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/OrgEleCho/EleCho.Internationalization&body=https://github.com/OrgEleCho/EleCho.Internationalization -39) [https://github.com/pekspro/DataAnnotationValuesExtractor]( https://github.com/pekspro/DataAnnotationValuesExtractor) , https://github.com/pekspro/DataAnnotationValuesExtractor +38) [https://github.com/pekspro/DataAnnotationValuesExtractor]( https://github.com/pekspro/DataAnnotationValuesExtractor) , https://github.com/pekspro/DataAnnotationValuesExtractor Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/pekspro/DataAnnotationValuesExtractor&body=https://github.com/pekspro/DataAnnotationValuesExtractor -40) [https://github.com/pierre3/PlantUmlClassDiagramGenerator]( https://github.com/pierre3/PlantUmlClassDiagramGenerator) , https://github.com/pierre3/PlantUmlClassDiagramGenerator +39) [https://github.com/pierre3/PlantUmlClassDiagramGenerator]( https://github.com/pierre3/PlantUmlClassDiagramGenerator) , https://github.com/pierre3/PlantUmlClassDiagramGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/pierre3/PlantUmlClassDiagramGenerator&body=https://github.com/pierre3/PlantUmlClassDiagramGenerator -41) [https://github.com/sebastienros/comptime]( https://github.com/sebastienros/comptime) , https://github.com/sebastienros/comptime +40) [https://github.com/sebastienros/comptime]( https://github.com/sebastienros/comptime) , https://github.com/sebastienros/comptime Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/sebastienros/comptime&body=https://github.com/sebastienros/comptime -42) [https://github.com/stbychkov/AutoLoggerMessage]( https://github.com/stbychkov/AutoLoggerMessage) , https://github.com/stbychkov/AutoLoggerMessage +41) [https://github.com/stbychkov/AutoLoggerMessage]( https://github.com/stbychkov/AutoLoggerMessage) , https://github.com/stbychkov/AutoLoggerMessage Why I have not tested : Microsoft have done same feature https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/stbychkov/AutoLoggerMessage&body=https://github.com/stbychkov/AutoLoggerMessage -43) [https://github.com/Stepami/visitor-net]( https://github.com/Stepami/visitor-net) , https://github.com/Stepami/visitor-net +42) [https://github.com/Stepami/visitor-net]( https://github.com/Stepami/visitor-net) , https://github.com/Stepami/visitor-net Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/Stepami/visitor-net&body=https://github.com/Stepami/visitor-net -44) [https://github.com/svee4/RequiredStaticMembers]( https://github.com/svee4/RequiredStaticMembers) , https://github.com/svee4/RequiredStaticMembers +43) [https://github.com/svee4/RequiredStaticMembers]( https://github.com/svee4/RequiredStaticMembers) , https://github.com/svee4/RequiredStaticMembers Why I have not tested : issue opened https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/svee4/RequiredStaticMembers&body=https://github.com/svee4/RequiredStaticMembers -45) [https://github.com/SzymonHalucha/Minerals.AutoCommands]( https://github.com/SzymonHalucha/Minerals.AutoCommands) , https://github.com/SzymonHalucha/Minerals.AutoCommands +44) [https://github.com/SzymonHalucha/Minerals.AutoCommands]( https://github.com/SzymonHalucha/Minerals.AutoCommands) , https://github.com/SzymonHalucha/Minerals.AutoCommands Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/SzymonHalucha/Minerals.AutoCommands&body=https://github.com/SzymonHalucha/Minerals.AutoCommands -46) [https://github.com/Teleopti/Saspect]( https://github.com/Teleopti/Saspect) , https://github.com/Teleopti/Saspect +45) [https://github.com/Teleopti/Saspect]( https://github.com/Teleopti/Saspect) , https://github.com/Teleopti/Saspect Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/Teleopti/Saspect&body=https://github.com/Teleopti/Saspect -47) [https://github.com/TheFo2sh/AsyncFlow]( https://github.com/TheFo2sh/AsyncFlow) , https://github.com/TheFo2sh/AsyncFlow +46) [https://github.com/TheFo2sh/AsyncFlow]( https://github.com/TheFo2sh/AsyncFlow) , https://github.com/TheFo2sh/AsyncFlow Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/TheFo2sh/AsyncFlow&body=https://github.com/TheFo2sh/AsyncFlow -48) [https://github.com/wieslawsoltes/ReactiveGenerator]( https://github.com/wieslawsoltes/ReactiveGenerator) , https://github.com/wieslawsoltes/ReactiveGenerator +47) [https://github.com/wieslawsoltes/ReactiveGenerator]( https://github.com/wieslawsoltes/ReactiveGenerator) , https://github.com/wieslawsoltes/ReactiveGenerator Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://github.com/wieslawsoltes/ReactiveGenerator&body=https://github.com/wieslawsoltes/ReactiveGenerator -49) [https://www.nuget.org/packages/Aspid.Generators.Helper]( https://www.nuget.org/packages/Aspid.Generators.Helper) , https://www.nuget.org/packages/Aspid.Generators.Helper +48) [https://www.nuget.org/packages/Aspid.Generators.Helper]( https://www.nuget.org/packages/Aspid.Generators.Helper) , https://www.nuget.org/packages/Aspid.Generators.Helper Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/Aspid.Generators.Helper&body=https://www.nuget.org/packages/Aspid.Generators.Helper -50) [https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator]( https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator) , https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator +49) [https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator]( https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator) , https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator&body=https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator -51) [https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ +50) [https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/&body=https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ -52) [https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ +51) [https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/&body=https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ -53) [https://www.nuget.org/packages/CTMGenerator]( https://www.nuget.org/packages/CTMGenerator) , https://www.nuget.org/packages/CTMGenerator +52) [https://www.nuget.org/packages/CTMGenerator]( https://www.nuget.org/packages/CTMGenerator) , https://www.nuget.org/packages/CTMGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/CTMGenerator&body=https://www.nuget.org/packages/CTMGenerator -54) [https://www.nuget.org/packages/DecoWeaver]( https://www.nuget.org/packages/DecoWeaver) , https://www.nuget.org/packages/DecoWeaver +53) [https://www.nuget.org/packages/DecoWeaver]( https://www.nuget.org/packages/DecoWeaver) , https://www.nuget.org/packages/DecoWeaver Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/DecoWeaver&body=https://www.nuget.org/packages/DecoWeaver -55) [https://www.nuget.org/packages/JsonDerivedTypeGenerator]( https://www.nuget.org/packages/JsonDerivedTypeGenerator) , https://www.nuget.org/packages/JsonDerivedTypeGenerator +54) [https://www.nuget.org/packages/JsonDerivedTypeGenerator]( https://www.nuget.org/packages/JsonDerivedTypeGenerator) , https://www.nuget.org/packages/JsonDerivedTypeGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/JsonDerivedTypeGenerator&body=https://www.nuget.org/packages/JsonDerivedTypeGenerator -56) [https://www.nuget.org/packages/MappingSourceGenerator]( https://www.nuget.org/packages/MappingSourceGenerator) , https://www.nuget.org/packages/MappingSourceGenerator +55) [https://www.nuget.org/packages/MappingSourceGenerator]( https://www.nuget.org/packages/MappingSourceGenerator) , https://www.nuget.org/packages/MappingSourceGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/MappingSourceGenerator&body=https://www.nuget.org/packages/MappingSourceGenerator -57) [https://www.nuget.org/packages/Optikode.FluentMapper]( https://www.nuget.org/packages/Optikode.FluentMapper) , https://www.nuget.org/packages/Optikode.FluentMapper +56) [https://www.nuget.org/packages/Optikode.FluentMapper]( https://www.nuget.org/packages/Optikode.FluentMapper) , https://www.nuget.org/packages/Optikode.FluentMapper Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/Optikode.FluentMapper&body=https://www.nuget.org/packages/Optikode.FluentMapper -58) [https://www.nuget.org/packages/SoapProxyPocoGenerator]( https://www.nuget.org/packages/SoapProxyPocoGenerator) , https://www.nuget.org/packages/SoapProxyPocoGenerator +57) [https://www.nuget.org/packages/SoapProxyPocoGenerator]( https://www.nuget.org/packages/SoapProxyPocoGenerator) , https://www.nuget.org/packages/SoapProxyPocoGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/SoapProxyPocoGenerator&body=https://www.nuget.org/packages/SoapProxyPocoGenerator -59) [https://www.nuget.org/packages/TinyMediator]( https://www.nuget.org/packages/TinyMediator) , https://www.nuget.org/packages/TinyMediator +58) [https://www.nuget.org/packages/TinyMediator]( https://www.nuget.org/packages/TinyMediator) , https://www.nuget.org/packages/TinyMediator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/TinyMediator&body=https://www.nuget.org/packages/TinyMediator -60) [https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder]( https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder) , https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder +59) [https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder]( https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder) , https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder&body=https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder -61) [https://www.nuget.org/packages/X39.Roslyn.Property]( https://www.nuget.org/packages/X39.Roslyn.Property) , https://www.nuget.org/packages/X39.Roslyn.Property +60) [https://www.nuget.org/packages/X39.Roslyn.Property]( https://www.nuget.org/packages/X39.Roslyn.Property) , https://www.nuget.org/packages/X39.Roslyn.Property Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/X39.Roslyn.Property&body=https://www.nuget.org/packages/X39.Roslyn.Property -62) [https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/]( https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/) , https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ +61) [https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/]( https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/) , https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/&body=https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ -63) [https://www.nuget.org/packages/ZeroReflection.Mediator.Generator]( https://www.nuget.org/packages/ZeroReflection.Mediator.Generator) , https://www.nuget.org/packages/ZeroReflection.Mediator.Generator +62) [https://www.nuget.org/packages/ZeroReflection.Mediator.Generator]( https://www.nuget.org/packages/ZeroReflection.Mediator.Generator) , https://www.nuget.org/packages/ZeroReflection.Mediator.Generator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=https://www.nuget.org/packages/ZeroReflection.Mediator.Generator&body=https://www.nuget.org/packages/ZeroReflection.Mediator.Generator -64) [Intellenum]( https://github.com/SteveDunn/Intellenum) , https://github.com/SteveDunn/Intellenum +63) [Intellenum]( https://github.com/SteveDunn/Intellenum) , https://github.com/SteveDunn/Intellenum Why I have not tested : not understand how to use https://github.com/ignatandrei/RSCG_Examples/issues/new?title=Intellenum&body=https://github.com/SteveDunn/Intellenum -65) [laker]( https://github.com/Lakerfield/Lakerfield.Rpc) , https://github.com/Lakerfield/Lakerfield.Rpc +64) [laker]( https://github.com/Lakerfield/Lakerfield.Rpc) , https://github.com/Lakerfield/Lakerfield.Rpc Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=laker&body=https://github.com/Lakerfield/Lakerfield.Rpc -66) [LoggingDecoratorGenerator]( https://github.com/DavidFineboym/LoggingDecoratorGenerator) , https://github.com/DavidFineboym/LoggingDecoratorGenerator +65) [LoggingDecoratorGenerator]( https://github.com/DavidFineboym/LoggingDecoratorGenerator) , https://github.com/DavidFineboym/LoggingDecoratorGenerator Why I have not tested : Microsoft have done same feature https://github.com/ignatandrei/RSCG_Examples/issues/new?title=LoggingDecoratorGenerator&body=https://github.com/DavidFineboym/LoggingDecoratorGenerator -67) [lucide-blazor]( https://github.com/brecht-vde/lucide-blazor/) , https://github.com/brecht-vde/lucide-blazor/ +66) [lucide-blazor]( https://github.com/brecht-vde/lucide-blazor/) , https://github.com/brecht-vde/lucide-blazor/ Why I have not tested : issue opened https://github.com/ignatandrei/RSCG_Examples/issues/new?title=lucide-blazor&body=https://github.com/brecht-vde/lucide-blazor/ -68) [ManagedDotnetProfiler]( https://github.com/kevingosse/ManagedDotnetProfiler) , https://github.com/kevingosse/ManagedDotnetProfiler +67) [ManagedDotnetProfiler]( https://github.com/kevingosse/ManagedDotnetProfiler) , https://github.com/kevingosse/ManagedDotnetProfiler Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=ManagedDotnetProfiler&body=https://github.com/kevingosse/ManagedDotnetProfiler -69) [Maui.BindableProperty.Generator]( https://github.com/rrmanzano/maui-bindableproperty-generator) , https://github.com/rrmanzano/maui-bindableproperty-generator +68) [Maui.BindableProperty.Generator]( https://github.com/rrmanzano/maui-bindableproperty-generator) , https://github.com/rrmanzano/maui-bindableproperty-generator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=Maui.BindableProperty.Generator&body=https://github.com/rrmanzano/maui-bindableproperty-generator -70) [Minerals.AutoCQRS]( https://github.com/SzymonHalucha/Minerals.AutoCQRS) , https://github.com/SzymonHalucha/Minerals.AutoCQRS +69) [Minerals.AutoCQRS]( https://github.com/SzymonHalucha/Minerals.AutoCQRS) , https://github.com/SzymonHalucha/Minerals.AutoCQRS Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=Minerals.AutoCQRS&body=https://github.com/SzymonHalucha/Minerals.AutoCQRS -71) [Minerals.AutoDomain]( https://github.com/SzymonHalucha/Minerals.AutoDomain) , https://github.com/SzymonHalucha/Minerals.AutoDomain +70) [Minerals.AutoDomain]( https://github.com/SzymonHalucha/Minerals.AutoDomain) , https://github.com/SzymonHalucha/Minerals.AutoDomain Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=Minerals.AutoDomain&body=https://github.com/SzymonHalucha/Minerals.AutoDomain -72) [observable]( https://github.com/notanaverageman/Bindables) , https://github.com/notanaverageman/Bindables +71) [observable]( https://github.com/notanaverageman/Bindables) , https://github.com/notanaverageman/Bindables Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=observable&body=https://github.com/notanaverageman/Bindables -73) [PolySharp]( https://github.com/Sergio0694/PolySharp) , https://github.com/Sergio0694/PolySharp +72) [PolySharp]( https://github.com/Sergio0694/PolySharp) , https://github.com/Sergio0694/PolySharp Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=PolySharp&body=https://github.com/Sergio0694/PolySharp -74) [RazorGen]( https://github.com/dartk/RazorGen) , https://github.com/dartk/RazorGen +73) [RazorGen]( https://github.com/dartk/RazorGen) , https://github.com/dartk/RazorGen Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=RazorGen&body=https://github.com/dartk/RazorGen -75) [SerdeDn]( https://github.com/serdedotnet/serde) , https://github.com/serdedotnet/serde +74) [SerdeDn]( https://github.com/serdedotnet/serde) , https://github.com/serdedotnet/serde Why I have not tested : serializer. Done by MSFT with System.Text.Json https://github.com/ignatandrei/RSCG_Examples/issues/new?title=SerdeDn&body=https://github.com/serdedotnet/serde -76) [SogePoco]( https://github.com/d-p-y/SogePoco) , https://github.com/d-p-y/SogePoco +75) [SogePoco]( https://github.com/d-p-y/SogePoco) , https://github.com/d-p-y/SogePoco Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=SogePoco&body=https://github.com/d-p-y/SogePoco -77) [SourceCrafter.HttpServiceClientGenerator]( https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/) , https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/ +76) [SourceCrafter.HttpServiceClientGenerator]( https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/) , https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/ Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=SourceCrafter.HttpServiceClientGenerator&body=https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/ -78) [ST.NSwag.ServerSourceGenerator]( https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator) , https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator +77) [ST.NSwag.ServerSourceGenerator]( https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator) , https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=ST.NSwag.ServerSourceGenerator&body=https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator -79) [StrongInject]( https://github.com/YairHalberstadt/stronginject/) , https://github.com/YairHalberstadt/stronginject/ +78) [StrongInject]( https://github.com/YairHalberstadt/stronginject/) , https://github.com/YairHalberstadt/stronginject/ Why I have not tested : later https://github.com/ignatandrei/RSCG_Examples/issues/new?title=StrongInject&body=https://github.com/YairHalberstadt/stronginject/ -80) [TeuJson]( https://github.com/Terria-K/TeuJson) , https://github.com/Terria-K/TeuJson +79) [TeuJson]( https://github.com/Terria-K/TeuJson) , https://github.com/Terria-K/TeuJson Why I have not tested : json a class, was done in System.Text.Json https://github.com/ignatandrei/RSCG_Examples/issues/new?title=TeuJson&body=https://github.com/Terria-K/TeuJson -81) [Tinyhand]( https://github.com/archi-Doc/Tinyhand) , https://github.com/archi-Doc/Tinyhand +80) [Tinyhand]( https://github.com/archi-Doc/Tinyhand) , https://github.com/archi-Doc/Tinyhand Why I have not tested : tried, need documentation https://github.com/ignatandrei/RSCG_Examples/issues/new?title=Tinyhand&body=https://github.com/archi-Doc/Tinyhand -82) [TupleOverloadGenerator]( https://github.com/ProphetLamb/TupleOverloadGenerator) , https://github.com/ProphetLamb/TupleOverloadGenerator +81) [TupleOverloadGenerator]( https://github.com/ProphetLamb/TupleOverloadGenerator) , https://github.com/ProphetLamb/TupleOverloadGenerator Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=TupleOverloadGenerator&body=https://github.com/ProphetLamb/TupleOverloadGenerator -83) [TypealizR]( https://github.com/earloc/TypealizR) , https://github.com/earloc/TypealizR +82) [TypealizR]( https://github.com/earloc/TypealizR) , https://github.com/earloc/TypealizR Why I have not tested : depends on Microsoft.Extensions.Localization https://github.com/ignatandrei/RSCG_Examples/issues/new?title=TypealizR&body=https://github.com/earloc/TypealizR -84) [UnitTestBlazor]( https://github.com/bUnit-dev/bUnit) , https://github.com/bUnit-dev/bUnit +83) [UnitTestBlazor]( https://github.com/bUnit-dev/bUnit) , https://github.com/bUnit-dev/bUnit Why I have not tested : issue opened https://github.com/ignatandrei/RSCG_Examples/issues/new?title=UnitTestBlazor&body=https://github.com/bUnit-dev/bUnit -85) [ValueLink]( https://github.com/archi-Doc/ValueLink) , https://github.com/archi-Doc/ValueLink +84) [ValueLink]( https://github.com/archi-Doc/ValueLink) , https://github.com/archi-Doc/ValueLink Why I have not tested : too complicated https://github.com/ignatandrei/RSCG_Examples/issues/new?title=ValueLink&body=https://github.com/archi-Doc/ValueLink -86) [VisitorPatternGenerator]( https://github.com/hikarin522/VisitorPatternGenerator/) , https://github.com/hikarin522/VisitorPatternGenerator/ +85) [VisitorPatternGenerator]( https://github.com/hikarin522/VisitorPatternGenerator/) , https://github.com/hikarin522/VisitorPatternGenerator/ Why I have not tested : issue opened https://github.com/ignatandrei/RSCG_Examples/issues/new?title=VisitorPatternGenerator&body=https://github.com/hikarin522/VisitorPatternGenerator/ -87) [WrapperValueObject]( https://github.com/martinothamar/WrapperValueObject) , https://github.com/martinothamar/WrapperValueObject +86) [WrapperValueObject]( https://github.com/martinothamar/WrapperValueObject) , https://github.com/martinothamar/WrapperValueObject Why I have not tested : not maintained as in readme diff --git a/later.md b/later.md index dc5f6c72c..7e1116972 100644 --- a/later.md +++ b/later.md @@ -1,6 +1,6 @@ # Just later -## Latest Update : 2026-02-01 => 01 February 2026 +## Latest Update : 2026-02-02 => 02 February 2026 @@ -38,241 +38,235 @@ Why I have not tested : later -6) [https://github.com/ANcpLua/ErrorOrX]( https://github.com/ANcpLua/ErrorOrX) , https://github.com/ANcpLua/ErrorOrX +6) [https://github.com/atc-net/atc-source-generators]( https://github.com/atc-net/atc-source-generators) , https://github.com/atc-net/atc-source-generators Why I have not tested : later -7) [https://github.com/atc-net/atc-source-generators]( https://github.com/atc-net/atc-source-generators) , https://github.com/atc-net/atc-source-generators +7) [https://github.com/Aymen83/AspectWeaver]( https://github.com/Aymen83/AspectWeaver) , https://github.com/Aymen83/AspectWeaver Why I have not tested : later -8) [https://github.com/Aymen83/AspectWeaver]( https://github.com/Aymen83/AspectWeaver) , https://github.com/Aymen83/AspectWeaver +8) [https://github.com/borisdj/CsCodeGenerator]( https://github.com/borisdj/CsCodeGenerator) , https://github.com/borisdj/CsCodeGenerator Why I have not tested : later -9) [https://github.com/borisdj/CsCodeGenerator]( https://github.com/borisdj/CsCodeGenerator) , https://github.com/borisdj/CsCodeGenerator +9) [https://github.com/buchmiet/FastFsm]( https://github.com/buchmiet/FastFsm) , https://github.com/buchmiet/FastFsm Why I have not tested : later -10) [https://github.com/buchmiet/FastFsm]( https://github.com/buchmiet/FastFsm) , https://github.com/buchmiet/FastFsm +10) [https://github.com/chickensoft-games/LogicBlocks]( https://github.com/chickensoft-games/LogicBlocks) , https://github.com/chickensoft-games/LogicBlocks Why I have not tested : later -11) [https://github.com/chickensoft-games/LogicBlocks]( https://github.com/chickensoft-games/LogicBlocks) , https://github.com/chickensoft-games/LogicBlocks +11) [https://github.com/FoundatioFx/Foundatio.Mediator]( https://github.com/FoundatioFx/Foundatio.Mediator) , https://github.com/FoundatioFx/Foundatio.Mediator Why I have not tested : later -12) [https://github.com/FoundatioFx/Foundatio.Mediator]( https://github.com/FoundatioFx/Foundatio.Mediator) , https://github.com/FoundatioFx/Foundatio.Mediator +12) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/ Why I have not tested : later -13) [https://github.com/IeuanWalker/MinimalApi.Endpoints/]( https://github.com/IeuanWalker/MinimalApi.Endpoints/) , https://github.com/IeuanWalker/MinimalApi.Endpoints/ +13) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface Why I have not tested : later -14) [https://github.com/MoslemBenDhaou/DataSurface]( https://github.com/MoslemBenDhaou/DataSurface) , https://github.com/MoslemBenDhaou/DataSurface +14) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate Why I have not tested : later -15) [https://github.com/mu-dawood/EasyValidate]( https://github.com/mu-dawood/EasyValidate) , https://github.com/mu-dawood/EasyValidate +15) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp Why I have not tested : later -16) [https://github.com/nuskey8/Csv-CSharp]( https://github.com/nuskey8/Csv-CSharp) , https://github.com/nuskey8/Csv-CSharp +16) [https://github.com/pekspro/DataAnnotationValuesExtractor]( https://github.com/pekspro/DataAnnotationValuesExtractor) , https://github.com/pekspro/DataAnnotationValuesExtractor Why I have not tested : later -17) [https://github.com/pekspro/DataAnnotationValuesExtractor]( https://github.com/pekspro/DataAnnotationValuesExtractor) , https://github.com/pekspro/DataAnnotationValuesExtractor +17) [https://github.com/pierre3/PlantUmlClassDiagramGenerator]( https://github.com/pierre3/PlantUmlClassDiagramGenerator) , https://github.com/pierre3/PlantUmlClassDiagramGenerator Why I have not tested : later -18) [https://github.com/pierre3/PlantUmlClassDiagramGenerator]( https://github.com/pierre3/PlantUmlClassDiagramGenerator) , https://github.com/pierre3/PlantUmlClassDiagramGenerator +18) [https://github.com/sebastienros/comptime]( https://github.com/sebastienros/comptime) , https://github.com/sebastienros/comptime Why I have not tested : later -19) [https://github.com/sebastienros/comptime]( https://github.com/sebastienros/comptime) , https://github.com/sebastienros/comptime +19) [https://github.com/Stepami/visitor-net]( https://github.com/Stepami/visitor-net) , https://github.com/Stepami/visitor-net Why I have not tested : later -20) [https://github.com/Stepami/visitor-net]( https://github.com/Stepami/visitor-net) , https://github.com/Stepami/visitor-net +20) [https://github.com/SzymonHalucha/Minerals.AutoCommands]( https://github.com/SzymonHalucha/Minerals.AutoCommands) , https://github.com/SzymonHalucha/Minerals.AutoCommands Why I have not tested : later -21) [https://github.com/SzymonHalucha/Minerals.AutoCommands]( https://github.com/SzymonHalucha/Minerals.AutoCommands) , https://github.com/SzymonHalucha/Minerals.AutoCommands +21) [https://github.com/Teleopti/Saspect]( https://github.com/Teleopti/Saspect) , https://github.com/Teleopti/Saspect Why I have not tested : later -22) [https://github.com/Teleopti/Saspect]( https://github.com/Teleopti/Saspect) , https://github.com/Teleopti/Saspect +22) [https://www.nuget.org/packages/Aspid.Generators.Helper]( https://www.nuget.org/packages/Aspid.Generators.Helper) , https://www.nuget.org/packages/Aspid.Generators.Helper Why I have not tested : later -23) [https://www.nuget.org/packages/Aspid.Generators.Helper]( https://www.nuget.org/packages/Aspid.Generators.Helper) , https://www.nuget.org/packages/Aspid.Generators.Helper +23) [https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator]( https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator) , https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator Why I have not tested : later -24) [https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator]( https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator) , https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator +24) [https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ Why I have not tested : later -25) [https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ +25) [https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ Why I have not tested : later -26) [https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/]( https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/) , https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ +26) [https://www.nuget.org/packages/CTMGenerator]( https://www.nuget.org/packages/CTMGenerator) , https://www.nuget.org/packages/CTMGenerator Why I have not tested : later -27) [https://www.nuget.org/packages/CTMGenerator]( https://www.nuget.org/packages/CTMGenerator) , https://www.nuget.org/packages/CTMGenerator +27) [https://www.nuget.org/packages/DecoWeaver]( https://www.nuget.org/packages/DecoWeaver) , https://www.nuget.org/packages/DecoWeaver Why I have not tested : later -28) [https://www.nuget.org/packages/DecoWeaver]( https://www.nuget.org/packages/DecoWeaver) , https://www.nuget.org/packages/DecoWeaver +28) [https://www.nuget.org/packages/JsonDerivedTypeGenerator]( https://www.nuget.org/packages/JsonDerivedTypeGenerator) , https://www.nuget.org/packages/JsonDerivedTypeGenerator Why I have not tested : later -29) [https://www.nuget.org/packages/JsonDerivedTypeGenerator]( https://www.nuget.org/packages/JsonDerivedTypeGenerator) , https://www.nuget.org/packages/JsonDerivedTypeGenerator +29) [https://www.nuget.org/packages/MappingSourceGenerator]( https://www.nuget.org/packages/MappingSourceGenerator) , https://www.nuget.org/packages/MappingSourceGenerator Why I have not tested : later -30) [https://www.nuget.org/packages/MappingSourceGenerator]( https://www.nuget.org/packages/MappingSourceGenerator) , https://www.nuget.org/packages/MappingSourceGenerator +30) [https://www.nuget.org/packages/Optikode.FluentMapper]( https://www.nuget.org/packages/Optikode.FluentMapper) , https://www.nuget.org/packages/Optikode.FluentMapper Why I have not tested : later -31) [https://www.nuget.org/packages/Optikode.FluentMapper]( https://www.nuget.org/packages/Optikode.FluentMapper) , https://www.nuget.org/packages/Optikode.FluentMapper +31) [https://www.nuget.org/packages/SoapProxyPocoGenerator]( https://www.nuget.org/packages/SoapProxyPocoGenerator) , https://www.nuget.org/packages/SoapProxyPocoGenerator Why I have not tested : later -32) [https://www.nuget.org/packages/SoapProxyPocoGenerator]( https://www.nuget.org/packages/SoapProxyPocoGenerator) , https://www.nuget.org/packages/SoapProxyPocoGenerator +32) [https://www.nuget.org/packages/TinyMediator]( https://www.nuget.org/packages/TinyMediator) , https://www.nuget.org/packages/TinyMediator Why I have not tested : later -33) [https://www.nuget.org/packages/TinyMediator]( https://www.nuget.org/packages/TinyMediator) , https://www.nuget.org/packages/TinyMediator +33) [https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder]( https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder) , https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder Why I have not tested : later -34) [https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder]( https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder) , https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder +34) [https://www.nuget.org/packages/X39.Roslyn.Property]( https://www.nuget.org/packages/X39.Roslyn.Property) , https://www.nuget.org/packages/X39.Roslyn.Property Why I have not tested : later -35) [https://www.nuget.org/packages/X39.Roslyn.Property]( https://www.nuget.org/packages/X39.Roslyn.Property) , https://www.nuget.org/packages/X39.Roslyn.Property +35) [https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/]( https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/) , https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ Why I have not tested : later -36) [https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/]( https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/) , https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ +36) [https://www.nuget.org/packages/ZeroReflection.Mediator.Generator]( https://www.nuget.org/packages/ZeroReflection.Mediator.Generator) , https://www.nuget.org/packages/ZeroReflection.Mediator.Generator Why I have not tested : later -37) [https://www.nuget.org/packages/ZeroReflection.Mediator.Generator]( https://www.nuget.org/packages/ZeroReflection.Mediator.Generator) , https://www.nuget.org/packages/ZeroReflection.Mediator.Generator +37) [Maui.BindableProperty.Generator]( https://github.com/rrmanzano/maui-bindableproperty-generator) , https://github.com/rrmanzano/maui-bindableproperty-generator Why I have not tested : later -38) [Maui.BindableProperty.Generator]( https://github.com/rrmanzano/maui-bindableproperty-generator) , https://github.com/rrmanzano/maui-bindableproperty-generator +38) [Minerals.AutoCQRS]( https://github.com/SzymonHalucha/Minerals.AutoCQRS) , https://github.com/SzymonHalucha/Minerals.AutoCQRS Why I have not tested : later -39) [Minerals.AutoCQRS]( https://github.com/SzymonHalucha/Minerals.AutoCQRS) , https://github.com/SzymonHalucha/Minerals.AutoCQRS +39) [Minerals.AutoDomain]( https://github.com/SzymonHalucha/Minerals.AutoDomain) , https://github.com/SzymonHalucha/Minerals.AutoDomain Why I have not tested : later -40) [Minerals.AutoDomain]( https://github.com/SzymonHalucha/Minerals.AutoDomain) , https://github.com/SzymonHalucha/Minerals.AutoDomain +40) [observable]( https://github.com/notanaverageman/Bindables) , https://github.com/notanaverageman/Bindables Why I have not tested : later -41) [observable]( https://github.com/notanaverageman/Bindables) , https://github.com/notanaverageman/Bindables +41) [RazorGen]( https://github.com/dartk/RazorGen) , https://github.com/dartk/RazorGen Why I have not tested : later -42) [RazorGen]( https://github.com/dartk/RazorGen) , https://github.com/dartk/RazorGen +42) [SourceCrafter.HttpServiceClientGenerator]( https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/) , https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/ Why I have not tested : later -43) [SourceCrafter.HttpServiceClientGenerator]( https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/) , https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/ +43) [ST.NSwag.ServerSourceGenerator]( https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator) , https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator Why I have not tested : later -44) [ST.NSwag.ServerSourceGenerator]( https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator) , https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator - -Why I have not tested : later - - - -45) [StrongInject]( https://github.com/YairHalberstadt/stronginject/) , https://github.com/YairHalberstadt/stronginject/ +44) [StrongInject]( https://github.com/YairHalberstadt/stronginject/) , https://github.com/YairHalberstadt/stronginject/ Why I have not tested : later diff --git a/v2/.tours/ErrorOrX.tour b/v2/.tours/ErrorOrX.tour new file mode 100644 index 000000000..b86c91c28 --- /dev/null +++ b/v2/.tours/ErrorOrX.tour @@ -0,0 +1,60 @@ + +{ + "$schema": "https://aka.ms/codetour-schema", + "title": "ErrorOrX", + "steps": + [ + { + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.csproj", + "description": "First, we add Nuget [ErrorOrX](https://www.nuget.org/packages/ErrorOrX/) in csproj ", + "pattern": "ErrorOrX" + } + + ,{ + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/PersonAPI.cs", + "description": "File PersonAPI.cs ", + "pattern": "this is the code" + } + + ,{ + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/Program.cs", + "description": "File Program.cs \r\n>> dotnet run --project rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.csproj ", + "pattern": "this is the code" + } + + + ,{ + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/obj/GX/ErrorOrX.Generators/ErrorOr.Generators.OpenApiTransformerGenerator/OpenApiTransformers.g.cs", + "description": "Generated File 5 from 5 : OpenApiTransformers.g.cs ", + "line": 1 + } + + ,{ + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/obj/GX/ErrorOrX.Generators/ErrorOr.Generators.ErrorOrEndpointGenerator/ErrorOrEndpoints.GlobalUsings.g.cs", + "description": "Generated File 4 from 5 : ErrorOrEndpoints.GlobalUsings.g.cs ", + "line": 1 + } + + ,{ + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/obj/GX/ErrorOrX.Generators/ErrorOr.Generators.ErrorOrEndpointGenerator/ErrorOrEndpointOptions.g.cs", + "description": "Generated File 3 from 5 : ErrorOrEndpointOptions.g.cs ", + "line": 1 + } + + ,{ + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/obj/GX/ErrorOrX.Generators/ErrorOr.Generators.ErrorOrEndpointGenerator/ErrorOrEndpointMappings.cs", + "description": "Generated File 2 from 5 : ErrorOrEndpointMappings.cs ", + "line": 1 + } + + ,{ + "file": "rscg_examples/ErrorOrX/src/DemoFuncAPI/obj/GX/ErrorOrX.Generators/ErrorOr.Generators.ErrorOrEndpointGenerator/ErrorOrEndpointAttributes.Mappings.g.cs", + "description": "Generated File 1 from 5 : ErrorOrEndpointAttributes.Mappings.g.cs ", + "line": 1 + } + + ], + + "ref": "main" + +} \ No newline at end of file diff --git a/v2/Generator/all.csv b/v2/Generator/all.csv index f0b893c78..003f38a36 100644 --- a/v2/Generator/all.csv +++ b/v2/Generator/all.csv @@ -252,3 +252,4 @@ Nr,Key,Source,Category 251,OrderedBuildersGenerator, https://github.com/Georgiy-Petrov/OrderedBuildersGenerator,Builder 252,RSCG_idempotency, https://github.com/ignatandrei/RSCG_idempotency,Idempotency 253,FastCloner, https://github.com/lofcz/FastCloner/,Clone +254,ErrorOrX, https://github.com/ANcpLua/ErrorOrX,API diff --git a/v2/RSCGExamplesData/GeneratorDataRec.json b/v2/RSCGExamplesData/GeneratorDataRec.json index 3de08bb7c..62b7082ba 100644 --- a/v2/RSCGExamplesData/GeneratorDataRec.json +++ b/v2/RSCGExamplesData/GeneratorDataRec.json @@ -1534,5 +1534,11 @@ "Category":29, "dtStart":"2026-02-01T00:00:00", "show":true + }, + { + "ID":"ErrorOrX", + "Category": 15, + "dtStart": "2026-02-02T00:00:00", + "show": true } ] \ No newline at end of file diff --git a/v2/RSCGExamplesData/NoExample.json b/v2/RSCGExamplesData/NoExample.json index f2b0349c7..7e93ffa9e 100644 --- a/v2/RSCGExamplesData/NoExample.json +++ b/v2/RSCGExamplesData/NoExample.json @@ -996,10 +996,6 @@ "ID":253, "name":"https://github.com/sebastienros/comptime", "why":"later" - }, - {"ID":256, - "name":"https://github.com/ANcpLua/ErrorOrX", - "why":"later" - } + } ] \ No newline at end of file diff --git a/v2/book/examples/ErrorOrX.html b/v2/book/examples/ErrorOrX.html new file mode 100644 index 000000000..bf8047088 --- /dev/null +++ b/v2/book/examples/ErrorOrX.html @@ -0,0 +1,79 @@ + +

RSCG nr 254 : ErrorOrX

+ +

Info

+Nuget : https://www.nuget.org/packages/ErrorOrX/ + +

You can find more details at : https://github.com/ANcpLua/ErrorOrX/

+ +

Author :Alexander Nachtmanns

+ +

Source: https://github.com/ANcpLua/ErrorOrX/

+ +

About

+ +API results from Functional returns of ErroOrX + +

+ How to use +

+

+ Add reference to the ErrorOrX in the csproj +

+ + +

This was for me the starting code

+ +
+ I have coded the file Program.cs +
+ +
+ +
+ I have coded the file PersonAPI.cs +
+ +
+

And here are the generated files

+ +
+ The file generated is ErrorOrEndpointAttributes.Mappings.g.cs +
+ + +
+ The file generated is ErrorOrEndpointMappings.cs +
+ + +
+ The file generated is ErrorOrEndpointOptions.g.cs +
+ + +
+ The file generated is ErrorOrEndpoints.GlobalUsings.g.cs +
+ + +
+ The file generated is OpenApiTransformers.g.cs +
+ + +

+ You can download the code and this page as pdf from + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX + +

+ + +

+ You can see the whole list at + + https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG + +

+ diff --git a/v2/book/list.html b/v2/book/list.html index 61b5f45b6..957e64006 100644 --- a/v2/book/list.html +++ b/v2/book/list.html @@ -17,7 +17,7 @@

-This is the list of 253 RSCG with examples => +This is the list of 254 RSCG with examples =>

@@ -1038,6 +1038,10 @@

+ + + +
253 FastCloner
254ErrorOrX
diff --git a/v2/book/pandocHTML.yaml b/v2/book/pandocHTML.yaml index dd50d4b06..0e2720b7a 100644 --- a/v2/book/pandocHTML.yaml +++ b/v2/book/pandocHTML.yaml @@ -267,6 +267,7 @@ input-files: - examples/OrderedBuildersGenerator.html - examples/RSCG_idempotency.html - examples/FastCloner.html +- examples/ErrorOrX.html # or you may use input-file: with a single value # defaults: diff --git a/v2/rscg_examples/ErrorOrX/description.json b/v2/rscg_examples/ErrorOrX/description.json new file mode 100644 index 000000000..489b1e510 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/description.json @@ -0,0 +1,22 @@ +{ + "generator":{ + "name":"ErrorOrX", + "nuget":[ + "https://www.nuget.org/packages/ErrorOrX/" + ], + "link":"https://github.com/ANcpLua/ErrorOrX", + "author":"Alexander Nachtmanns", + "source":"https://github.com/ANcpLua/ErrorOrX" + }, + "data":{ + "goodFor":["API results from Functional returns of ErroOrX"], + "csprojDemo":"DemoFuncAPI.csproj", + "csFiles":["Program.cs","PersonAPI.cs"], + "excludeDirectoryGenerated":["Microsoft.AspNetCore.App.SourceGenerators","Microsoft.AspNetCore.OpenApi.SourceGenerators"], + "includeAdditionalFiles":[""] + }, + "links":{ + "blog":"", + "video":"" + } +} \ No newline at end of file diff --git a/v2/rscg_examples/ErrorOrX/nuget.txt b/v2/rscg_examples/ErrorOrX/nuget.txt new file mode 100644 index 000000000..bd5f221cb --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/nuget.txt @@ -0,0 +1 @@ +A discriminated union type for .NET with source-generated ASP.NET Core Minimal API integration. Zero boilerplate, full AOT support. \ No newline at end of file diff --git a/v2/rscg_examples/ErrorOrX/readme.txt b/v2/rscg_examples/ErrorOrX/readme.txt new file mode 100644 index 000000000..11f0fd145 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/readme.txt @@ -0,0 +1,334 @@ +# ErrorOrX + +[![NuGet](https://img.shields.io/nuget/v/ErrorOrX.Generators.svg)](https://www.nuget.org/packages/ErrorOrX.Generators/) +[![NuGet Downloads](https://img.shields.io/nuget/dt/ErrorOrX.Generators.svg)](https://www.nuget.org/packages/ErrorOrX.Generators/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +Railway-Oriented Programming for .NET with source-generated ASP.NET Core Minimal API integration. Zero boilerplate, full +Native AOT support. + +## Features + +- **Discriminated Unions** - `ErrorOr` represents success or a list of typed errors +- **Fluent API** - Chain operations with `Then`, `Else`, `Match`, `Switch`, and `FailIf` +- **Nullable Extensions** - Convert nullable values with `OrNotFound()`, `OrValidation()`, and more +- **Source Generator** - Auto-generates `MapErrorOrEndpoints()` from attributed static methods +- **Smart Binding** - Automatic parameter inference based on HTTP method and type +- **OpenAPI Ready** - Typed `Results<...>` unions for complete API documentation +- **Native AOT** - Reflection-free code generation with JSON serialization contexts +- **Middleware Support** - Translates ASP.NET Core attributes to Minimal API fluent calls (authorization, rate limiting, + caching) +- **API Versioning** - Integrates with Asp.Versioning.Http for versioned endpoint groups +- **41 Analyzers** - Real-time IDE feedback for route conflicts, binding errors, AOT compatibility + +## What the Generator Produces + +The source generator transforms your handler methods into complete ASP.NET Core Minimal API endpoints. +You write the business logic, the generator handles everything else. + +### Endpoint Wiring + +For each `[Get]`, `[Post]`, `[Put]`, `[Delete]`, `[Patch]` method: + +- Registers endpoint with `app.MapGet()`, `app.MapPost()`, etc. +- Applies route constraints (`{id:guid}`, `{count:int}`) +- Sets operation name (`.WithName()`) and tags (`.WithTags()`) + +[See EndpointMetadataEmitter.cs](src/ErrorOrX.Generators/Emitters/EndpointMetadataEmitter.cs) + +### Parameter Binding + +Automatic inference based on type and HTTP method: + +| Source | Inference Rule | +|---------|-----------------------------------------------------------------------| +| Route | Parameter name matches `{param}` in route | +| Query | Primitive type not in route | +| Body | POST/PUT/PATCH with complex type | +| Service | Interface, abstract, or DI naming pattern (`*Service`, `*Repository`) | +| Special | `HttpContext`, `CancellationToken`, `IFormFile` | + +[See BindingCodeEmitter.cs](src/ErrorOrX.Generators/Emitters/BindingCodeEmitter.cs) + +### Error-to-HTTP Mapping + +Converts `ErrorOr` errors to proper HTTP responses with [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) +ProblemDetails: + +| ErrorType | HTTP Status | Response | +|--------------|-------------|---------------------------------------| +| Validation | 400 | `ValidationProblem` with field errors | +| Unauthorized | 401 | `Unauthorized()` | +| Forbidden | 403 | `Forbid()` | +| NotFound | 404 | `NotFound` | +| Conflict | 409 | `Conflict` | +| Failure | 500 | `InternalServerError` | +| Unexpected | 500 | `InternalServerError` | +| Custom(422) | 422 | `UnprocessableEntity` | + +[See ErrorMapping.cs](src/ErrorOrX.Generators/Models/ErrorMapping.cs) + +### Request Validation + +Generated code validates before calling your handler: + +- Required parameters (returns 400 if missing) +- Type parsing (Guid, int, etc. with format errors) +- JSON deserialization (catches `JsonException`) +- Content-Type checking (returns 415 for wrong type) + +### OpenAPI Metadata + +Full OpenAPI documentation without manual attributes: + +- Response types via `ProducesResponseTypeMetadata` +- Accept types via `AcceptsMetadata` +- Tags from class name +- Operation IDs from method name +- XML doc comments extracted to summaries + +[See OpenApiTransformerGenerator.cs](src/ErrorOrX.Generators/OpenApiTransformerGenerator.cs) + +### Builder API + +Fluent configuration following ASP.NET Core patterns: + +```csharp +builder.Services.AddErrorOrEndpoints() + .UseJsonContext() // AOT JSON + .WithCamelCase() // Property naming + .WithIgnoreNulls(); // Skip null values + +app.MapErrorOrEndpoints() + .RequireAuthorization() // Global auth + .RequireRateLimiting("api"); // Global rate limit +``` + +### Analyzers (38 Diagnostics) + +Real-time IDE feedback covering: + +| Category | Diagnostics | Examples | +|------------|-------------|----------------------------------------------------------------------| +| Core | EOE001-007 | Invalid return type, non-static handler, unbound route param | +| Binding | EOE008-021 | Multiple body sources, invalid `[FromRoute]` type, ambiguous binding | +| Results | EOE022-024 | Too many result types, unknown error factory, undocumented interface | +| AOT/JSON | EOE025-026 | Missing camelCase, missing JsonSerializerContext | +| Versioning | EOE027-031 | Version-neutral conflict, undeclared version, invalid format | +| Naming | EOE032-033 | Duplicate route binding, non-PascalCase handler | +| AOT Safety | EOE034-038 | `Activator.CreateInstance`, `dynamic`, `Expression.Compile()` | + +[See Descriptors.cs](src/ErrorOrX.Generators/Analyzers/Descriptors.cs) + +## Installation + +```bash +dotnet add package ErrorOrX.Generators +``` + +This package includes both the source generator and the `ErrorOrX` runtime library. + +## Quick Start + +```csharp +// Program.cs +var app = WebApplication.CreateSlimBuilder(args).Build(); +app.MapErrorOrEndpoints(); +app.Run(); +``` + +```csharp +// TodoApi.cs +using ErrorOr; + +public static class TodoApi +{ + [Get("/todos/{id:guid}")] + public static ErrorOr GetById(Guid id, ITodoService svc) + => svc.GetById(id).OrNotFound($"Todo {id} not found"); + + [Post("/todos")] + public static ErrorOr Create(CreateTodoRequest req, ITodoService svc) + => svc.Create(req); // 201 Created + + [Delete("/todos/{id:guid}")] + public static ErrorOr Delete(Guid id, ITodoService svc) + => svc.Delete(id) ? Result.Deleted : Error.NotFound(); +} +``` + +## Error Types + +Create structured errors mapped to HTTP status codes: + +```csharp +Error.Validation("User.InvalidEmail", "Email format is invalid") // 400 +Error.Unauthorized("Auth.InvalidToken", "Token has expired") // 401 +Error.Forbidden("Auth.InsufficientRole", "Admin role required") // 403 +Error.NotFound("User.NotFound", "User does not exist") // 404 +Error.Conflict("User.Duplicate", "Email already registered") // 409 +Error.Failure("Db.ConnectionFailed", "Database unavailable") // 500 +Error.Unexpected("Unknown", "An unexpected error occurred") // 500 +Error.Custom(422, "Validation.Complex", "Complex validation failed") +``` + +## Nullable-to-ErrorOr Extensions + +Convert nullable values to `ErrorOr` with auto-generated error codes: + +```csharp +// Error code auto-generated from type name (e.g., "Todo.NotFound") +return _todos.Find(t => t.Id == id).OrNotFound($"Todo {id} not found"); +return user.OrUnauthorized("Invalid credentials"); +return record.OrValidation("Record is invalid"); + +// Custom errors +return value.OrError(Error.Custom(422, "Custom.Code", "Custom message")); +return value.OrError(() => BuildExpensiveError()); // Lazy evaluation +``` + +| Extension | Error Type | HTTP | Description | +|---------------------|--------------|------|--------------------------| +| `.OrNotFound()` | NotFound | 404 | Resource not found | +| `.OrValidation()` | Validation | 400 | Input validation failed | +| `.OrUnauthorized()` | Unauthorized | 401 | Authentication required | +| `.OrForbidden()` | Forbidden | 403 | Insufficient permissions | +| `.OrConflict()` | Conflict | 409 | State conflict | +| `.OrFailure()` | Failure | 500 | Operational failure | +| `.OrUnexpected()` | Unexpected | 500 | Unexpected error | +| `.OrError(Error)` | Any | Any | Custom error | +| `.OrError(Func)` | Any | Any | Lazy custom error | + +## Fluent API + +Chain operations using railway-oriented programming patterns: + +```csharp +// Chain operations - errors short-circuit the pipeline +var result = ValidateOrder(request) + .Then(order => ProcessPayment(order)) + .Then(order => CreateShipment(order)) + .FailIf(order => order.Total <= 0, Error.Validation("Order.InvalidTotal", "Total must be positive")); + +// Handle both cases +return result.Match( + order => Ok(order), + errors => BadRequest(errors.First().Description)); + +// Provide fallback on error +var user = GetUser(id).Else(errors => DefaultUser); + +// Side effects +GetUser(id).Switch( + user => Console.WriteLine($"Found: {user.Name}"), + errors => Logger.LogError(errors.First().Description)); +``` + +## Result Markers + +Use semantic markers for endpoints without response bodies: + +```csharp +Result.Success // 200 OK (no body) +Result.Created // 201 Created (no body) +Result.Updated // 204 No Content +Result.Deleted // 204 No Content +``` + +## Interface Types with `[ReturnsError]` + +Document possible errors on interface methods for OpenAPI generation: + +```csharp +public interface ITodoService +{ + [ReturnsError(ErrorType.NotFound, "Todo.NotFound")] + [ReturnsError(ErrorType.Validation, "Todo.Invalid")] + ErrorOr GetById(Guid id); +} + +[Get("/todos/{id:guid}")] +public static ErrorOr GetById(Guid id, ITodoService svc) => + svc.GetById(id); +// Generates: Results, NotFound, ValidationProblem> +``` + +The generator reads `[ReturnsError]` attributes from interface/abstract methods to build the complete `Results<...>` +union for OpenAPI documentation. + +## Smart Parameter Binding + +The generator automatically infers parameter sources: + +```csharp +[Post("/todos")] +public static ErrorOr Create( + CreateTodoRequest req, // -> Body (POST + complex type) + ITodoService svc) // -> Service (interface) + => svc.Create(req); + +[Get("/todos/{id:guid}")] +public static ErrorOr GetById( + Guid id, // -> Route (matches {id}) + ITodoService svc) // -> Service + => svc.GetById(id).OrNotFound(); +``` + +## Middleware Attributes + +Standard ASP.NET Core attributes on your handler methods are translated to Minimal API fluent calls: + +```csharp +[Post("/admin")] +[Authorize("Admin")] // ASP.NET Core authorization +[EnableRateLimiting("fixed")] // Microsoft.AspNetCore.RateLimiting +[OutputCache(Duration = 60)] // ASP.NET Core output caching +public static ErrorOr CreateAdmin(CreateUserRequest req) { } + +// Generator emits: +// app.MapPost("/admin", handler) +// .RequireAuthorization("Admin") +// .RequireRateLimiting("fixed") +// .CacheOutput(policy => policy.Expire(TimeSpan.FromSeconds(60))); +``` + +## Native AOT + +Fully compatible with `PublishAot=true`. Create a `JsonSerializerContext` with your endpoint types: + +```csharp +[JsonSourceGenerationOptions( + PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +[JsonSerializable(typeof(Todo))] +[JsonSerializable(typeof(CreateTodoRequest))] +[JsonSerializable(typeof(ProblemDetails))] +internal partial class AppJsonSerializerContext : JsonSerializerContext; +``` + +Register it with ErrorOrEndpoints: + +```csharp +var builder = WebApplication.CreateSlimBuilder(args); + +builder.Services.AddErrorOrEndpoints() + .UseJsonContext(); // Uses options from [JsonSourceGenerationOptions] + +var app = builder.Build(); +app.MapErrorOrEndpoints(); +app.Run(); +``` + +The `[JsonSourceGenerationOptions]` on your context controls serialization behavior (camelCase, null handling). +The builder methods `WithCamelCase()` and `WithIgnoreNulls()` are only needed if you want to override at runtime. + +## Packages + +| Package | Target | Description | +|-----------------------|------------------|--------------------------------------| +| `ErrorOrX.Generators` | `netstandard2.0` | Source generator (includes ErrorOrX) | +| `ErrorOrX` | `net10.0` | Runtime library (auto-referenced) | + +## Changelog + +See [CHANGELOG.md](CHANGELOG.md) for version history. diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI.slnx b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI.slnx new file mode 100644 index 000000000..b43d68157 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI.slnx @@ -0,0 +1,3 @@ + + + diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.csproj b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.csproj new file mode 100644 index 000000000..68c078f8e --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.csproj @@ -0,0 +1,20 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + true + $(BaseIntermediateOutputPath)\GX + + diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.http b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.http new file mode 100644 index 000000000..52bdd0284 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/DemoFuncAPI.http @@ -0,0 +1,6 @@ +@DemoFuncAPI_HostAddress = http://localhost:5194 + +GET {{DemoFuncAPI_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/PersonAPI.cs b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/PersonAPI.cs new file mode 100644 index 000000000..79ae0db81 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/PersonAPI.cs @@ -0,0 +1,32 @@ +using ErrorOr; + +namespace DemoFuncAPI; + +public static class PersonAPI +{ + + [Get("/todos/{id}")] + public static ErrorOr GetById(int id) + { + try + { + return GetPersonById(id).OrNotFound(); + } + catch (Exception ex) + { + return Error.Failure(description: ex.Message); + } + } + + static Person? GetPersonById(int id) => + + id switch + { + 1 => new Person(1, "John Doe"), + 2 => throw new Exception("person does not exists"), + _ => null + }; + +} + +public record Person(int Id, string Name) ; diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/Program.cs b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/Program.cs new file mode 100644 index 000000000..f0a5de763 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/Program.cs @@ -0,0 +1,44 @@ +using OpenAPISwaggerUI; + +var builder = WebApplication.CreateBuilder(args); + +//instead of this +//builder.Services.AddOpenApi(); +builder.Services.AddErrorOrOpenApi(); +builder.Services.AddErrorOrEndpoints(); +var app = builder.Build(); + +// Configure the HTTP request pipeline. +//if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); + app.UseOpenAPISwaggerUI(); +} +app.MapErrorOrEndpoints(); +//app.UseHttpsRedirection(); + +var summaries = new[] +{ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" +}; + +app.MapGet("/weatherforecast", () => +{ + var forecast = Enumerable.Range(1, 5).Select(index => + new WeatherForecast + ( + DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + Random.Shared.Next(-20, 55), + summaries[Random.Shared.Next(summaries.Length)] + )) + .ToArray(); + return forecast; +}) +.WithName("GetWeatherForecast"); + +app.Run(); + +internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) +{ + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); +} diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/Properties/launchSettings.json b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/Properties/launchSettings.json new file mode 100644 index 000000000..8a619a089 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/Properties/launchSettings.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5194", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7128;http://localhost:5194", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/appsettings.Development.json b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/appsettings.Development.json new file mode 100644 index 000000000..0c208ae91 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/appsettings.json b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/appsettings.json new file mode 100644 index 000000000..10f68b8c8 --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/src/DemoFuncAPI/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/v2/rscg_examples/ErrorOrX/video.json b/v2/rscg_examples/ErrorOrX/video.json new file mode 100644 index 000000000..ac3df791c --- /dev/null +++ b/v2/rscg_examples/ErrorOrX/video.json @@ -0,0 +1,39 @@ +{ + "scriptName": "ErrorOrX", + "steps": +[ + {"typeStep":"exec","arg":"clipchamp.exe launch"}, + {"typeStep":"text","arg": "Welcome to Roslyn Examples"}, + {"typeStep":"text","arg":"If you want to see more examples , see List Of RSCG"}, + {"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG"}, + {"typeStep":"text","arg": "My name is Andrei Ignat and I am deeply fond of Roslyn Source Code Generator. "}, + +{"typeStep":"text","arg": "Today I will present ErrorOrX . API results from Functional returns of ErroOrX ."}, +{"typeStep":"browser","arg":"https://www.nuget.org/packages/ErrorOrX/"}, +{"typeStep":"text","arg": "The whole example is here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX"}, +{"typeStep":"text","arg": "You can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX#download-example-net--c-"}, +{"typeStep":"text","arg":"Here is the code downloaded "}, +{"typeStep":"exec","arg":"explorer.exe /select,D:\\gth\\RSCG_Examples\\v2\\Generator.sln"}, +{"typeStep":"text","arg": "So , let's start the project with Visual Studio Code "}, +{"typeStep":"stepvscode","arg": "-n D:\\gth\\RSCG_Examples\\v2"}, + +{"typeStep":"text","arg": "To use it ,you will put the Nuget ErrorOrX into the csproj "}, + +{"typeStep":"stepvscode","arg": "-r -g D:\\gth\\RSCG_Examples\\v2\\rscg_examples\\ErrorOrX\\src\\DemoFuncAPI\\DemoFuncAPI.csproj"}, + +{"typeStep":"text","arg": "And now I will show you an example of using ErrorOrX"}, + +{"typeStep":"hide","arg": "now execute the tour in VSCode"}, +{"typeStep":"tour", "arg": "src/.tours/"}, +{"typeStep":"text","arg":" And I will execute the project"}, +{"typeStep":"showproj", "arg":"DemoFuncAPI.csproj"}, +{"typeStep":"text","arg":" This concludes the project"}, +{"typeStep":"waitseconds","arg":"30"}, +{"typeStep":"text","arg": "Remember, you can download the code from here"}, +{"typeStep":"browser","arg":"https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX#download-example-net--c-", +SpeakTest=" "}, +{"typeStep":"waitseconds","arg":"30"}, +] +} diff --git a/v2/rscg_examples_site/docs/Authors/Alexander_Nachtmanns.md b/v2/rscg_examples_site/docs/Authors/Alexander_Nachtmanns.md new file mode 100644 index 000000000..622910433 --- /dev/null +++ b/v2/rscg_examples_site/docs/Authors/Alexander_Nachtmanns.md @@ -0,0 +1,7 @@ +# Author : Alexander Nachtmanns + +Number RSCG: 1 + + + 1 [ErrorOrX](/docs/ErrorOrX) [![Nuget](https://img.shields.io/nuget/dt/ErrorOrX?label=ErrorOrX)](https://www.nuget.org/packages/ErrorOrX/) ![GitHub Repo stars](https://img.shields.io/github/stars/ANcpLua/ErrorOrX?style=social) 2026-02-02 + diff --git a/v2/rscg_examples_site/docs/Categories/API.md b/v2/rscg_examples_site/docs/Categories/API.md index 7401e734b..a8cd9b9e7 100644 --- a/v2/rscg_examples_site/docs/Categories/API.md +++ b/v2/rscg_examples_site/docs/Categories/API.md @@ -1,26 +1,28 @@

API

-Number RSCG: 11 +Number RSCG: 12 - 1 [immediate.apis](/docs/immediate.apis) [![Nuget](https://img.shields.io/nuget/dt/immediate.apis?label=immediate.apis)](https://www.nuget.org/packages/immediate.apis/) ![GitHub Repo stars](https://img.shields.io/github/stars/immediateplatform/immediate.apis?style=social) 2025-03-27 + 1 [ErrorOrX](/docs/ErrorOrX) [![Nuget](https://img.shields.io/nuget/dt/ErrorOrX?label=ErrorOrX)](https://www.nuget.org/packages/ErrorOrX/) ![GitHub Repo stars](https://img.shields.io/github/stars/ANcpLua/ErrorOrX?style=social) 2026-02-02 - 2 [Microsoft.Extensions.Configuration.Binder](/docs/Microsoft.Extensions.Configuration.Binder) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Configuration.Binder?label=Microsoft.Extensions.Configuration.Binder)](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) ![GitHub Repo stars](https://img.shields.io/learn.microsoft/stars/en-us/dotnet?style=social) 2023-11-18 + 2 [immediate.apis](/docs/immediate.apis) [![Nuget](https://img.shields.io/nuget/dt/immediate.apis?label=immediate.apis)](https://www.nuget.org/packages/immediate.apis/) ![GitHub Repo stars](https://img.shields.io/github/stars/immediateplatform/immediate.apis?style=social) 2025-03-27 - 3 [MinimalApiBuilder](/docs/MinimalApiBuilder) [![Nuget](https://img.shields.io/nuget/dt/MinimalApiBuilder?label=MinimalApiBuilder)](https://www.nuget.org/packages/MinimalApiBuilder/) ![GitHub Repo stars](https://img.shields.io/github/stars/JensDll/MinimalApiBuilder?style=social) 2023-10-26 + 3 [Microsoft.Extensions.Configuration.Binder](/docs/Microsoft.Extensions.Configuration.Binder) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Configuration.Binder?label=Microsoft.Extensions.Configuration.Binder)](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) ![GitHub Repo stars](https://img.shields.io/learn.microsoft/stars/en-us/dotnet?style=social) 2023-11-18 - 4 [MinimalApis.Discovery](/docs/MinimalApis.Discovery) [![Nuget](https://img.shields.io/nuget/dt/MinimalApis.Discovery?label=MinimalApis.Discovery)](https://www.nuget.org/packages/MinimalApis.Discovery/) ![GitHub Repo stars](https://img.shields.io/github/stars/shawnwildermuth/MinimalApis?style=social) 2024-04-16 + 4 [MinimalApiBuilder](/docs/MinimalApiBuilder) [![Nuget](https://img.shields.io/nuget/dt/MinimalApiBuilder?label=MinimalApiBuilder)](https://www.nuget.org/packages/MinimalApiBuilder/) ![GitHub Repo stars](https://img.shields.io/github/stars/JensDll/MinimalApiBuilder?style=social) 2023-10-26 - 5 [MinimalHelpers.Routing.Analyzers](/docs/MinimalHelpers.Routing.Analyzers) [![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.Routing.Analyzers?label=MinimalHelpers.Routing.Analyzers)](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers/) ![GitHub Repo stars](https://img.shields.io/github/stars/marcominerva/MinimalHelpers?style=social) 2024-10-21 + 5 [MinimalApis.Discovery](/docs/MinimalApis.Discovery) [![Nuget](https://img.shields.io/nuget/dt/MinimalApis.Discovery?label=MinimalApis.Discovery)](https://www.nuget.org/packages/MinimalApis.Discovery/) ![GitHub Repo stars](https://img.shields.io/github/stars/shawnwildermuth/MinimalApis?style=social) 2024-04-16 - 6 [RDG](/docs/RDG) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Http?label=Microsoft.Extensions.Http)](https://www.nuget.org/packages/Microsoft.Extensions.Http) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2023-11-19 + 6 [MinimalHelpers.Routing.Analyzers](/docs/MinimalHelpers.Routing.Analyzers) [![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.Routing.Analyzers?label=MinimalHelpers.Routing.Analyzers)](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers/) ![GitHub Repo stars](https://img.shields.io/github/stars/marcominerva/MinimalHelpers?style=social) 2024-10-21 - 7 [Refit](/docs/Refit) [![Nuget](https://img.shields.io/nuget/dt/Refit?label=Refit)](https://www.nuget.org/packages/Refit/) ![GitHub Repo stars](https://img.shields.io/github/stars/reactiveui/refit?style=social) 2023-07-31 + 7 [RDG](/docs/RDG) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Http?label=Microsoft.Extensions.Http)](https://www.nuget.org/packages/Microsoft.Extensions.Http) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2023-11-19 - 8 [RSCG_WebAPIExports](/docs/RSCG_WebAPIExports) [![Nuget](https://img.shields.io/nuget/dt/RSCG_WebAPIExports?label=RSCG_WebAPIExports)](https://www.nuget.org/packages/RSCG_WebAPIExports/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_WebAPIExports?style=social) 2023-08-23 + 8 [Refit](/docs/Refit) [![Nuget](https://img.shields.io/nuget/dt/Refit?label=Refit)](https://www.nuget.org/packages/Refit/) ![GitHub Repo stars](https://img.shields.io/github/stars/reactiveui/refit?style=social) 2023-07-31 - 9 [SafeRouting](/docs/SafeRouting) [![Nuget](https://img.shields.io/nuget/dt/SafeRouting?label=SafeRouting)](https://www.nuget.org/packages/SafeRouting/) ![GitHub Repo stars](https://img.shields.io/github/stars/daviddotcs/safe-routing?style=social) 2023-09-23 + 9 [RSCG_WebAPIExports](/docs/RSCG_WebAPIExports) [![Nuget](https://img.shields.io/nuget/dt/RSCG_WebAPIExports?label=RSCG_WebAPIExports)](https://www.nuget.org/packages/RSCG_WebAPIExports/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_WebAPIExports?style=social) 2023-08-23 - 10 [SkinnyControllersCommon](/docs/SkinnyControllersCommon) [![Nuget](https://img.shields.io/nuget/dt/SkinnyControllersCommon?label=SkinnyControllersCommon)](https://www.nuget.org/packages/SkinnyControllersCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/SkinnyControllersGenerator?style=social) 2023-04-16 + 10 [SafeRouting](/docs/SafeRouting) [![Nuget](https://img.shields.io/nuget/dt/SafeRouting?label=SafeRouting)](https://www.nuget.org/packages/SafeRouting/) ![GitHub Repo stars](https://img.shields.io/github/stars/daviddotcs/safe-routing?style=social) 2023-09-23 - 11 [XmlCommentGenerator](/docs/XmlCommentGenerator) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/dotnet?style=social) 2025-11-09 + 11 [SkinnyControllersCommon](/docs/SkinnyControllersCommon) [![Nuget](https://img.shields.io/nuget/dt/SkinnyControllersCommon?label=SkinnyControllersCommon)](https://www.nuget.org/packages/SkinnyControllersCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/SkinnyControllersGenerator?style=social) 2023-04-16 + + 12 [XmlCommentGenerator](/docs/XmlCommentGenerator) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/dotnet?style=social) 2025-11-09 \ No newline at end of file diff --git a/v2/rscg_examples_site/docs/Categories/_PrimitiveAPI.mdx b/v2/rscg_examples_site/docs/Categories/_PrimitiveAPI.mdx index 783bcf43d..f03b03c95 100644 --- a/v2/rscg_examples_site/docs/Categories/_PrimitiveAPI.mdx +++ b/v2/rscg_examples_site/docs/Categories/_PrimitiveAPI.mdx @@ -1,26 +1,28 @@ ### Category "API" has the following generators: - 1 [immediate.apis](/docs/immediate.apis) [![Nuget](https://img.shields.io/nuget/dt/immediate.apis?label=immediate.apis)](https://www.nuget.org/packages/immediate.apis/) ![GitHub Repo stars](https://img.shields.io/github/stars/immediateplatform/immediate.apis?style=social) 2025-03-27 + 1 [ErrorOrX](/docs/ErrorOrX) [![Nuget](https://img.shields.io/nuget/dt/ErrorOrX?label=ErrorOrX)](https://www.nuget.org/packages/ErrorOrX/) ![GitHub Repo stars](https://img.shields.io/github/stars/ANcpLua/ErrorOrX?style=social) 2026-02-02 - 2 [Microsoft.Extensions.Configuration.Binder](/docs/Microsoft.Extensions.Configuration.Binder) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Configuration.Binder?label=Microsoft.Extensions.Configuration.Binder)](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) ![GitHub Repo stars](https://img.shields.io/learn.microsoft/stars/en-us/dotnet?style=social) 2023-11-18 + 2 [immediate.apis](/docs/immediate.apis) [![Nuget](https://img.shields.io/nuget/dt/immediate.apis?label=immediate.apis)](https://www.nuget.org/packages/immediate.apis/) ![GitHub Repo stars](https://img.shields.io/github/stars/immediateplatform/immediate.apis?style=social) 2025-03-27 - 3 [MinimalApiBuilder](/docs/MinimalApiBuilder) [![Nuget](https://img.shields.io/nuget/dt/MinimalApiBuilder?label=MinimalApiBuilder)](https://www.nuget.org/packages/MinimalApiBuilder/) ![GitHub Repo stars](https://img.shields.io/github/stars/JensDll/MinimalApiBuilder?style=social) 2023-10-26 + 3 [Microsoft.Extensions.Configuration.Binder](/docs/Microsoft.Extensions.Configuration.Binder) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Configuration.Binder?label=Microsoft.Extensions.Configuration.Binder)](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.Binder/) ![GitHub Repo stars](https://img.shields.io/learn.microsoft/stars/en-us/dotnet?style=social) 2023-11-18 - 4 [MinimalApis.Discovery](/docs/MinimalApis.Discovery) [![Nuget](https://img.shields.io/nuget/dt/MinimalApis.Discovery?label=MinimalApis.Discovery)](https://www.nuget.org/packages/MinimalApis.Discovery/) ![GitHub Repo stars](https://img.shields.io/github/stars/shawnwildermuth/MinimalApis?style=social) 2024-04-16 + 4 [MinimalApiBuilder](/docs/MinimalApiBuilder) [![Nuget](https://img.shields.io/nuget/dt/MinimalApiBuilder?label=MinimalApiBuilder)](https://www.nuget.org/packages/MinimalApiBuilder/) ![GitHub Repo stars](https://img.shields.io/github/stars/JensDll/MinimalApiBuilder?style=social) 2023-10-26 - 5 [MinimalHelpers.Routing.Analyzers](/docs/MinimalHelpers.Routing.Analyzers) [![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.Routing.Analyzers?label=MinimalHelpers.Routing.Analyzers)](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers/) ![GitHub Repo stars](https://img.shields.io/github/stars/marcominerva/MinimalHelpers?style=social) 2024-10-21 + 5 [MinimalApis.Discovery](/docs/MinimalApis.Discovery) [![Nuget](https://img.shields.io/nuget/dt/MinimalApis.Discovery?label=MinimalApis.Discovery)](https://www.nuget.org/packages/MinimalApis.Discovery/) ![GitHub Repo stars](https://img.shields.io/github/stars/shawnwildermuth/MinimalApis?style=social) 2024-04-16 - 6 [RDG](/docs/RDG) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Http?label=Microsoft.Extensions.Http)](https://www.nuget.org/packages/Microsoft.Extensions.Http) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2023-11-19 + 6 [MinimalHelpers.Routing.Analyzers](/docs/MinimalHelpers.Routing.Analyzers) [![Nuget](https://img.shields.io/nuget/dt/MinimalHelpers.Routing.Analyzers?label=MinimalHelpers.Routing.Analyzers)](https://www.nuget.org/packages/MinimalHelpers.Routing.Analyzers/) ![GitHub Repo stars](https://img.shields.io/github/stars/marcominerva/MinimalHelpers?style=social) 2024-10-21 - 7 [Refit](/docs/Refit) [![Nuget](https://img.shields.io/nuget/dt/Refit?label=Refit)](https://www.nuget.org/packages/Refit/) ![GitHub Repo stars](https://img.shields.io/github/stars/reactiveui/refit?style=social) 2023-07-31 + 7 [RDG](/docs/RDG) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.Extensions.Http?label=Microsoft.Extensions.Http)](https://www.nuget.org/packages/Microsoft.Extensions.Http) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/aspnetcore?style=social) 2023-11-19 - 8 [RSCG_WebAPIExports](/docs/RSCG_WebAPIExports) [![Nuget](https://img.shields.io/nuget/dt/RSCG_WebAPIExports?label=RSCG_WebAPIExports)](https://www.nuget.org/packages/RSCG_WebAPIExports/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_WebAPIExports?style=social) 2023-08-23 + 8 [Refit](/docs/Refit) [![Nuget](https://img.shields.io/nuget/dt/Refit?label=Refit)](https://www.nuget.org/packages/Refit/) ![GitHub Repo stars](https://img.shields.io/github/stars/reactiveui/refit?style=social) 2023-07-31 - 9 [SafeRouting](/docs/SafeRouting) [![Nuget](https://img.shields.io/nuget/dt/SafeRouting?label=SafeRouting)](https://www.nuget.org/packages/SafeRouting/) ![GitHub Repo stars](https://img.shields.io/github/stars/daviddotcs/safe-routing?style=social) 2023-09-23 + 9 [RSCG_WebAPIExports](/docs/RSCG_WebAPIExports) [![Nuget](https://img.shields.io/nuget/dt/RSCG_WebAPIExports?label=RSCG_WebAPIExports)](https://www.nuget.org/packages/RSCG_WebAPIExports/) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/RSCG_WebAPIExports?style=social) 2023-08-23 - 10 [SkinnyControllersCommon](/docs/SkinnyControllersCommon) [![Nuget](https://img.shields.io/nuget/dt/SkinnyControllersCommon?label=SkinnyControllersCommon)](https://www.nuget.org/packages/SkinnyControllersCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/SkinnyControllersGenerator?style=social) 2023-04-16 + 10 [SafeRouting](/docs/SafeRouting) [![Nuget](https://img.shields.io/nuget/dt/SafeRouting?label=SafeRouting)](https://www.nuget.org/packages/SafeRouting/) ![GitHub Repo stars](https://img.shields.io/github/stars/daviddotcs/safe-routing?style=social) 2023-09-23 - 11 [XmlCommentGenerator](/docs/XmlCommentGenerator) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/dotnet?style=social) 2025-11-09 + 11 [SkinnyControllersCommon](/docs/SkinnyControllersCommon) [![Nuget](https://img.shields.io/nuget/dt/SkinnyControllersCommon?label=SkinnyControllersCommon)](https://www.nuget.org/packages/SkinnyControllersCommon) ![GitHub Repo stars](https://img.shields.io/github/stars/ignatandrei/SkinnyControllersGenerator?style=social) 2023-04-16 + + 12 [XmlCommentGenerator](/docs/XmlCommentGenerator) [![Nuget](https://img.shields.io/nuget/dt/Microsoft.AspNetCore.OpenApi?label=Microsoft.AspNetCore.OpenApi)](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi/) ![GitHub Repo stars](https://img.shields.io/github/stars/dotnet/dotnet?style=social) 2025-11-09 ### See category diff --git a/v2/rscg_examples_site/docs/NoExamples.md b/v2/rscg_examples_site/docs/NoExamples.md index 5c9a9f2b2..054ed0601 100644 --- a/v2/rscg_examples_site/docs/NoExamples.md +++ b/v2/rscg_examples_site/docs/NoExamples.md @@ -266,539 +266,535 @@ Why I have not put example: issue opened Why I have not put example: too complicated -66)https://github.com/ANcpLua/ErrorOrX https://github.com/ANcpLua/ErrorOrX +66)https://github.com/atc-net/atc-source-generators https://github.com/atc-net/atc-source-generators Why I have not put example: later -67)https://github.com/atc-net/atc-source-generators https://github.com/atc-net/atc-source-generators - -Why I have not put example: later - -68)https://github.com/Atoen/TextLocalizer https://github.com/Atoen/TextLocalizer +67)https://github.com/Atoen/TextLocalizer https://github.com/Atoen/TextLocalizer Why I have not put example: too complicated -69)https://github.com/Aymen83/AspectWeaver https://github.com/Aymen83/AspectWeaver +68)https://github.com/Aymen83/AspectWeaver https://github.com/Aymen83/AspectWeaver Why I have not put example: later -70)https://github.com/bjornhellander/TestInheritanceGenerator https://github.com/bjornhellander/TestInheritanceGenerator +69)https://github.com/bjornhellander/TestInheritanceGenerator https://github.com/bjornhellander/TestInheritanceGenerator Why I have not put example: too complicated -71)https://github.com/borisdj/CsCodeGenerator https://github.com/borisdj/CsCodeGenerator +70)https://github.com/borisdj/CsCodeGenerator https://github.com/borisdj/CsCodeGenerator Why I have not put example: later -72)https://github.com/buchmiet/FastFsm https://github.com/buchmiet/FastFsm +71)https://github.com/buchmiet/FastFsm https://github.com/buchmiet/FastFsm Why I have not put example: later -73)https://github.com/chickensoft-games/LogicBlocks https://github.com/chickensoft-games/LogicBlocks +72)https://github.com/chickensoft-games/LogicBlocks https://github.com/chickensoft-games/LogicBlocks Why I have not put example: later -74)https://github.com/dgmjr-io/InterfaceGenerator https://github.com/dgmjr-io/InterfaceGenerator +73)https://github.com/dgmjr-io/InterfaceGenerator https://github.com/dgmjr-io/InterfaceGenerator Why I have not put example: issue opened -75)https://github.com/eddievelasquez/IntercodeToolbox https://github.com/eddievelasquez/IntercodeToolbox +74)https://github.com/eddievelasquez/IntercodeToolbox https://github.com/eddievelasquez/IntercodeToolbox Why I have not put example: too complicated -76)https://github.com/FoundatioFx/Foundatio.Mediator https://github.com/FoundatioFx/Foundatio.Mediator +75)https://github.com/FoundatioFx/Foundatio.Mediator https://github.com/FoundatioFx/Foundatio.Mediator Why I have not put example: later -77)https://github.com/GaoNian-NET/MapperToolkit https://github.com/GaoNian-NET/MapperToolkit +76)https://github.com/GaoNian-NET/MapperToolkit https://github.com/GaoNian-NET/MapperToolkit Why I have not put example: issue opened -78)https://github.com/IeuanWalker/MinimalApi.Endpoints/ https://github.com/IeuanWalker/MinimalApi.Endpoints/ +77)https://github.com/IeuanWalker/MinimalApi.Endpoints/ https://github.com/IeuanWalker/MinimalApi.Endpoints/ Why I have not put example: later -79)https://github.com/inputfalken/Dynatello https://github.com/inputfalken/Dynatello +78)https://github.com/inputfalken/Dynatello https://github.com/inputfalken/Dynatello Why I have not put example: too complicated -80)https://github.com/ionite34/MinimalApiMapper https://github.com/ionite34/MinimalApiMapper +79)https://github.com/ionite34/MinimalApiMapper https://github.com/ionite34/MinimalApiMapper Why I have not put example: own idea where to generate files, so overwrites -81)https://github.com/JasonBock/CslaGeneratorSerialization https://github.com/JasonBock/CslaGeneratorSerialization +80)https://github.com/JasonBock/CslaGeneratorSerialization https://github.com/JasonBock/CslaGeneratorSerialization Why I have not put example: too complicated -82)https://github.com/MoslemBenDhaou/DataSurface https://github.com/MoslemBenDhaou/DataSurface +81)https://github.com/MoslemBenDhaou/DataSurface https://github.com/MoslemBenDhaou/DataSurface Why I have not put example: later -83)https://github.com/mu-dawood/EasyValidate https://github.com/mu-dawood/EasyValidate +82)https://github.com/mu-dawood/EasyValidate https://github.com/mu-dawood/EasyValidate Why I have not put example: later -84)https://github.com/nevsnirG/MinimalRichDomain https://github.com/nevsnirG/MinimalRichDomain +83)https://github.com/nevsnirG/MinimalRichDomain https://github.com/nevsnirG/MinimalRichDomain Why I have not put example: old ISourceGenerator -85)https://github.com/nuskey8/Csv-CSharp https://github.com/nuskey8/Csv-CSharp +84)https://github.com/nuskey8/Csv-CSharp https://github.com/nuskey8/Csv-CSharp Why I have not put example: later -86)https://github.com/OrgEleCho/EleCho.Internationalization https://github.com/OrgEleCho/EleCho.Internationalization +85)https://github.com/OrgEleCho/EleCho.Internationalization https://github.com/OrgEleCho/EleCho.Internationalization Why I have not put example: issue opened -87)https://github.com/pekspro/DataAnnotationValuesExtractor https://github.com/pekspro/DataAnnotationValuesExtractor +86)https://github.com/pekspro/DataAnnotationValuesExtractor https://github.com/pekspro/DataAnnotationValuesExtractor Why I have not put example: later -88)https://github.com/pierre3/PlantUmlClassDiagramGenerator https://github.com/pierre3/PlantUmlClassDiagramGenerator +87)https://github.com/pierre3/PlantUmlClassDiagramGenerator https://github.com/pierre3/PlantUmlClassDiagramGenerator Why I have not put example: later -89)https://github.com/ramhari-dev/PropGenAoT https://github.com/ramhari-dev/PropGenAoT +88)https://github.com/ramhari-dev/PropGenAoT https://github.com/ramhari-dev/PropGenAoT Why I have not put example: no readme -90)https://github.com/sebastienros/comptime https://github.com/sebastienros/comptime +89)https://github.com/sebastienros/comptime https://github.com/sebastienros/comptime Why I have not put example: later -91)https://github.com/stbychkov/AutoLoggerMessage https://github.com/stbychkov/AutoLoggerMessage +90)https://github.com/stbychkov/AutoLoggerMessage https://github.com/stbychkov/AutoLoggerMessage Why I have not put example: Microsoft have done same feature -92)https://github.com/Stepami/visitor-net https://github.com/Stepami/visitor-net +91)https://github.com/Stepami/visitor-net https://github.com/Stepami/visitor-net Why I have not put example: later -93)https://github.com/svee4/RequiredStaticMembers https://github.com/svee4/RequiredStaticMembers +92)https://github.com/svee4/RequiredStaticMembers https://github.com/svee4/RequiredStaticMembers Why I have not put example: issue opened -94)https://github.com/SzymonHalucha/Minerals.AutoCommands https://github.com/SzymonHalucha/Minerals.AutoCommands +93)https://github.com/SzymonHalucha/Minerals.AutoCommands https://github.com/SzymonHalucha/Minerals.AutoCommands Why I have not put example: later -95)https://github.com/Teleopti/Saspect https://github.com/Teleopti/Saspect +94)https://github.com/Teleopti/Saspect https://github.com/Teleopti/Saspect Why I have not put example: later -96)https://github.com/TheFo2sh/AsyncFlow https://github.com/TheFo2sh/AsyncFlow +95)https://github.com/TheFo2sh/AsyncFlow https://github.com/TheFo2sh/AsyncFlow Why I have not put example: too complicated -97)https://github.com/wieslawsoltes/ReactiveGenerator https://github.com/wieslawsoltes/ReactiveGenerator +96)https://github.com/wieslawsoltes/ReactiveGenerator https://github.com/wieslawsoltes/ReactiveGenerator Why I have not put example: too complicated -98)https://www.nuget.org/packages/Aspid.Generators.Helper https://www.nuget.org/packages/Aspid.Generators.Helper +97)https://www.nuget.org/packages/Aspid.Generators.Helper https://www.nuget.org/packages/Aspid.Generators.Helper Why I have not put example: later -99)https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator +98)https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator https://www.nuget.org/packages/AsyncTaskOrchestratorGenerator Why I have not put example: later -100)https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ +99)https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ https://www.nuget.org/packages/Csla.Generator.AutoImplementProperties.CSharp/ Why I have not put example: later -101)https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ +100)https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ https://www.nuget.org/packages/Csla.Generator.AutoSerialization.CSharp/ Why I have not put example: later -102)https://www.nuget.org/packages/CTMGenerator https://www.nuget.org/packages/CTMGenerator +101)https://www.nuget.org/packages/CTMGenerator https://www.nuget.org/packages/CTMGenerator Why I have not put example: later -103)https://www.nuget.org/packages/DecoWeaver https://www.nuget.org/packages/DecoWeaver +102)https://www.nuget.org/packages/DecoWeaver https://www.nuget.org/packages/DecoWeaver Why I have not put example: later -104)https://www.nuget.org/packages/JsonDerivedTypeGenerator https://www.nuget.org/packages/JsonDerivedTypeGenerator +103)https://www.nuget.org/packages/JsonDerivedTypeGenerator https://www.nuget.org/packages/JsonDerivedTypeGenerator Why I have not put example: later -105)https://www.nuget.org/packages/MappingSourceGenerator https://www.nuget.org/packages/MappingSourceGenerator +104)https://www.nuget.org/packages/MappingSourceGenerator https://www.nuget.org/packages/MappingSourceGenerator Why I have not put example: later -106)https://www.nuget.org/packages/Optikode.FluentMapper https://www.nuget.org/packages/Optikode.FluentMapper +105)https://www.nuget.org/packages/Optikode.FluentMapper https://www.nuget.org/packages/Optikode.FluentMapper Why I have not put example: later -107)https://www.nuget.org/packages/SoapProxyPocoGenerator https://www.nuget.org/packages/SoapProxyPocoGenerator +106)https://www.nuget.org/packages/SoapProxyPocoGenerator https://www.nuget.org/packages/SoapProxyPocoGenerator Why I have not put example: later -108)https://www.nuget.org/packages/TinyMediator https://www.nuget.org/packages/TinyMediator +107)https://www.nuget.org/packages/TinyMediator https://www.nuget.org/packages/TinyMediator Why I have not put example: later -109)https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder +108)https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder https://www.nuget.org/packages/TomRR.SourceGenerator.SettingsBinder Why I have not put example: later -110)https://www.nuget.org/packages/X39.Roslyn.Property https://www.nuget.org/packages/X39.Roslyn.Property +109)https://www.nuget.org/packages/X39.Roslyn.Property https://www.nuget.org/packages/X39.Roslyn.Property Why I have not put example: later -111)https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ +110)https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ https://www.nuget.org/packages/ZeroReflection.Mapper.Generator/ Why I have not put example: later -112)https://www.nuget.org/packages/ZeroReflection.Mediator.Generator https://www.nuget.org/packages/ZeroReflection.Mediator.Generator +111)https://www.nuget.org/packages/ZeroReflection.Mediator.Generator https://www.nuget.org/packages/ZeroReflection.Mediator.Generator Why I have not put example: later -113)HubClientProxyGenerator https://www.nuget.org/packages/Microsoft.AspNetCore.SignalR.Client.SourceGenerator +112)HubClientProxyGenerator https://www.nuget.org/packages/Microsoft.AspNetCore.SignalR.Client.SourceGenerator Why I have not put example: not having nuget, but having IIncrementalGenerator -114)Imp.NET https://github.com/DouglasDwyer/Imp.NET +113)Imp.NET https://github.com/DouglasDwyer/Imp.NET Why I have not put example: old ISourceGenerator -115)Intellenum https://github.com/SteveDunn/Intellenum +114)Intellenum https://github.com/SteveDunn/Intellenum Why I have not put example: not understand how to use -116)InterfaceGenerator https://github.com/daver32/InterfaceGenerator +115)InterfaceGenerator https://github.com/daver32/InterfaceGenerator Why I have not put example: old ISourceGenerator -117)IoTHubClientGenerator https://github.com/alonf/IoTHubClientGenerator +116)IoTHubClientGenerator https://github.com/alonf/IoTHubClientGenerator Why I have not put example: old ISourceGenerator -118)JsonByExampleGenerator https://github.com/hermanussen/JsonByExampleGenerator +117)JsonByExampleGenerator https://github.com/hermanussen/JsonByExampleGenerator Why I have not put example: old ISourceGenerator -119)JsonDeserializeResourceSourceGenerator https://github.com/musictopia2/JsonDeserializeResourceSourceGenerator +118)JsonDeserializeResourceSourceGenerator https://github.com/musictopia2/JsonDeserializeResourceSourceGenerator Why I have not put example: no readme -120)JsonMergePatch https://github.com/ladeak/JsonMergePatch +119)JsonMergePatch https://github.com/ladeak/JsonMergePatch Why I have not put example: old ISourceGenerator -121)JsonSerializerContextGenerator https://github.com/musictopia2/JsonSerializerContextGenerator +120)JsonSerializerContextGenerator https://github.com/musictopia2/JsonSerializerContextGenerator Why I have not put example: no readme -122)JsonSourceGenerator https://github.com/Pilchie/JsonSourceGenerator +121)JsonSourceGenerator https://github.com/Pilchie/JsonSourceGenerator Why I have not put example: not having nuget, but having IIncrementalGenerator -123)JsonSrcGen https://github.com/trampster/JsonSrcGen +122)JsonSrcGen https://github.com/trampster/JsonSrcGen Why I have not put example: old ISourceGenerator -124)kli.Localize https://github.com/kl1mm/localize +123)kli.Localize https://github.com/kl1mm/localize Why I have not put example: old ISourceGenerator -125)laker https://github.com/Lakerfield/Lakerfield.Rpc +124)laker https://github.com/Lakerfield/Lakerfield.Rpc Why I have not put example: too complicated -126)lambdajection https://github.com/cythral/lambdajection +125)lambdajection https://github.com/cythral/lambdajection Why I have not put example: old ISourceGenerator -127)Lazysh https://github.com/B1Z0N/LazyshGen +126)Lazysh https://github.com/B1Z0N/LazyshGen Why I have not put example: old ISourceGenerator -128)LoggingDecoratorGenerator https://github.com/DavidFineboym/LoggingDecoratorGenerator +127)LoggingDecoratorGenerator https://github.com/DavidFineboym/LoggingDecoratorGenerator Why I have not put example: Microsoft have done same feature -129)lucide-blazor https://github.com/brecht-vde/lucide-blazor/ +128)lucide-blazor https://github.com/brecht-vde/lucide-blazor/ Why I have not put example: issue opened -130)ManagedDotnetProfiler https://github.com/kevingosse/ManagedDotnetProfiler +129)ManagedDotnetProfiler https://github.com/kevingosse/ManagedDotnetProfiler Why I have not put example: too complicated -131)MapDataReader https://github.com/jitbit/MapDataReader +130)MapDataReader https://github.com/jitbit/MapDataReader Why I have not put example: old ISourceGenerator -132)MappingCloningExtensions https://github.com/musictopia2/MappingCloningExtensions +131)MappingCloningExtensions https://github.com/musictopia2/MappingCloningExtensions Why I have not put example: no readme -133)Maui.BindableProperty.Generator https://github.com/rrmanzano/maui-bindableproperty-generator +132)Maui.BindableProperty.Generator https://github.com/rrmanzano/maui-bindableproperty-generator Why I have not put example: later -134)MediatR https://github.com/Burgyn/MMLib.MediatR.Generators +133)MediatR https://github.com/Burgyn/MMLib.MediatR.Generators Why I have not put example: old ISourceGenerator -135)MemberAccessGenerator https://github.com/ufcpp/MemberAccessGenerator +134)MemberAccessGenerator https://github.com/ufcpp/MemberAccessGenerator Why I have not put example: old ISourceGenerator -136)MemoizeSourceGenerator https://github.com/Zoxive/MemoizeSourceGenerator +135)MemoizeSourceGenerator https://github.com/Zoxive/MemoizeSourceGenerator Why I have not put example: old ISourceGenerator -137)Minerals.AutoCQRS https://github.com/SzymonHalucha/Minerals.AutoCQRS +136)Minerals.AutoCQRS https://github.com/SzymonHalucha/Minerals.AutoCQRS Why I have not put example: later -138)Minerals.AutoDomain https://github.com/SzymonHalucha/Minerals.AutoDomain +137)Minerals.AutoDomain https://github.com/SzymonHalucha/Minerals.AutoDomain Why I have not put example: later -139)MiniRazor https://github.com/Tyrrrz/MiniRazor/ +138)MiniRazor https://github.com/Tyrrrz/MiniRazor/ Why I have not put example: archived -140)MockableStaticGenerator https://github.com/HamedFathi/MockableStaticGenerator +139)MockableStaticGenerator https://github.com/HamedFathi/MockableStaticGenerator Why I have not put example: old ISourceGenerator -141)MockGen https://github.com/thomas-girotto/MockGen +140)MockGen https://github.com/thomas-girotto/MockGen Why I have not put example: old ISourceGenerator -142)MockSourceGenerator https://github.com/hermanussen/MockSourceGenerator +141)MockSourceGenerator https://github.com/hermanussen/MockSourceGenerator Why I have not put example: old ISourceGenerator -143)MrMeeseeks.DIE https://github.com/Yeah69/MrMeeseeks.DIE +142)MrMeeseeks.DIE https://github.com/Yeah69/MrMeeseeks.DIE Why I have not put example: old ISourceGenerator -144)MrMeeseeks.ResXToViewModelGenerator https://github.com/Yeah69/MrMeeseeks.ResXToViewModelGenerator +143)MrMeeseeks.ResXToViewModelGenerator https://github.com/Yeah69/MrMeeseeks.ResXToViewModelGenerator Why I have not put example: old ISourceGenerator -145)MrMeeseeks.StaticDelegateGenerator https://github.com/Yeah69/MrMeeseeks.StaticDelegateGenerator +144)MrMeeseeks.StaticDelegateGenerator https://github.com/Yeah69/MrMeeseeks.StaticDelegateGenerator Why I have not put example: old ISourceGenerator -146)MrMeeseeks.Visitor https://github.com/Yeah69/MrMeeseeks.Visitor +145)MrMeeseeks.Visitor https://github.com/Yeah69/MrMeeseeks.Visitor Why I have not put example: old ISourceGenerator -147)Neon.Roslyn https://www.nuget.org/packages/Neon.Roslyn +146)Neon.Roslyn https://www.nuget.org/packages/Neon.Roslyn Why I have not put example: old ISourceGenerator -148)net_automatic_interface https://github.com/codecentric/net_automatic_interface +147)net_automatic_interface https://github.com/codecentric/net_automatic_interface Why I have not put example: old ISourceGenerator -149)NSourceGenerators https://github.com/NeVeSpl/NSourceGenerators/ +148)NSourceGenerators https://github.com/NeVeSpl/NSourceGenerators/ Why I have not put example: old ISourceGenerator -150)observable https://github.com/notanaverageman/Bindables +149)observable https://github.com/notanaverageman/Bindables Why I have not put example: later -151)Pipelines https://github.com/DumplingsDevs/Pipelines/ +150)Pipelines https://github.com/DumplingsDevs/Pipelines/ Why I have not put example: old ISourceGenerator -152)Plastic https://github.com/sang-hyeon/Plastic +151)Plastic https://github.com/sang-hyeon/Plastic Why I have not put example: old ISourceGenerator -153)PolySharp https://github.com/Sergio0694/PolySharp +152)PolySharp https://github.com/Sergio0694/PolySharp Why I have not put example: too complicated -154)PrimaryConstructor https://github.com/chaowlert/PrimaryConstructor +153)PrimaryConstructor https://github.com/chaowlert/PrimaryConstructor Why I have not put example: old ISourceGenerator -155)PrimitiveStaticDataGenerator https://github.com/iiweis/PrimitiveStaticDataGenerator +154)PrimitiveStaticDataGenerator https://github.com/iiweis/PrimitiveStaticDataGenerator Why I have not put example: old ISourceGenerator -156)PrintMembersGenerator https://github.com/Youssef1313/PrintMembersGenerator +155)PrintMembersGenerator https://github.com/Youssef1313/PrintMembersGenerator Why I have not put example: old ISourceGenerator -157)ProxyInterfaceGenerator https://github.com/StefH/ProxyInterfaceSourceGenerator +156)ProxyInterfaceGenerator https://github.com/StefH/ProxyInterfaceSourceGenerator Why I have not put example: old ISourceGenerator -158)PureHDF https://github.com/Apollo3zehn/PureHDF +157)PureHDF https://github.com/Apollo3zehn/PureHDF Why I have not put example: old ISourceGenerator -159)RazorGen https://github.com/dartk/RazorGen +158)RazorGen https://github.com/dartk/RazorGen Why I have not put example: later -160)RazorPageRouteGenerator https://github.com/surgicalcoder/RazorPageRouteGenerator +159)RazorPageRouteGenerator https://github.com/surgicalcoder/RazorPageRouteGenerator Why I have not put example: old ISourceGenerator -161)ReForge.Union https://github.com/nalcorso/ReForge.Union +160)ReForge.Union https://github.com/nalcorso/ReForge.Union Why I have not put example: not having nuget, but having IIncrementalGenerator -162)RoslynWeave https://github.com/Jishun/RoslynWeave +161)RoslynWeave https://github.com/Jishun/RoslynWeave Why I have not put example: old ISourceGenerator -163)ScenarioTests https://github.com/koenbeuk/ScenarioTests +162)ScenarioTests https://github.com/koenbeuk/ScenarioTests Why I have not put example: old ISourceGenerator -164)SerdeDn https://github.com/serdedotnet/serde +163)SerdeDn https://github.com/serdedotnet/serde Why I have not put example: serializer. Done by MSFT with System.Text.Json -165)SmallSharp https://github.com/devlooped/SmallSharp +164)SmallSharp https://github.com/devlooped/SmallSharp Why I have not put example: old ISourceGenerator -166)SmartAnnotations https://github.com/fiseni/SmartAnnotations +165)SmartAnnotations https://github.com/fiseni/SmartAnnotations Why I have not put example: old ISourceGenerator -167)SogePoco https://github.com/d-p-y/SogePoco +166)SogePoco https://github.com/d-p-y/SogePoco Why I have not put example: too complicated -168)SourceApi https://github.com/alekshura/SourceApi +167)SourceApi https://github.com/alekshura/SourceApi Why I have not put example: old ISourceGenerator -169)SourceConfig https://github.com/alekshura/SourceConfig +168)SourceConfig https://github.com/alekshura/SourceConfig Why I have not put example: old ISourceGenerator -170)SourceCrafter.HttpServiceClientGenerator https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/ +169)SourceCrafter.HttpServiceClientGenerator https://github.com/pedro-gilmora/SourceCrafter.HttpServiceClientGenerator/ Why I have not put example: later -171)SourceGeneratorQuery https://github.com/roeibajayo/SourceGeneratorQuery +170)SourceGeneratorQuery https://github.com/roeibajayo/SourceGeneratorQuery Why I have not put example: old ISourceGenerator -172)SourceInject https://github.com/giggio/sourceinject/ +171)SourceInject https://github.com/giggio/sourceinject/ Why I have not put example: old ISourceGenerator -173)SourceMapper https://github.com/alekshura/SourceMapper +172)SourceMapper https://github.com/alekshura/SourceMapper Why I have not put example: old ISourceGenerator -174)SourceMapper https://github.com/paiden/SourceMapper/ +173)SourceMapper https://github.com/paiden/SourceMapper/ Why I have not put example: old ISourceGenerator -175)SqlMarshal https://github.com/kant2002/SqlMarshal +174)SqlMarshal https://github.com/kant2002/SqlMarshal Why I have not put example: old ISourceGenerator -176)ST.NSwag.ServerSourceGenerator https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator +175)ST.NSwag.ServerSourceGenerator https://github.com/s-tarasov/ST.NSwag.ServerSourceGenerator Why I have not put example: later -177)StackXML https://github.com/ZingBallyhoo/StackXML +176)StackXML https://github.com/ZingBallyhoo/StackXML Why I have not put example: old ISourceGenerator -178)StaticProxyGenerator https://github.com/robertturner/StaticProxyGenerator +177)StaticProxyGenerator https://github.com/robertturner/StaticProxyGenerator Why I have not put example: old ISourceGenerator -179)StrongInject https://github.com/YairHalberstadt/stronginject/ +178)StrongInject https://github.com/YairHalberstadt/stronginject/ Why I have not put example: later -180)StronglyTypedEmbeddedResources https://github.com/surgicalcoder/StronglyTypedEmbeddedResources +179)StronglyTypedEmbeddedResources https://github.com/surgicalcoder/StronglyTypedEmbeddedResources Why I have not put example: old ISourceGenerator -181)StructPacker https://github.com/RudolfKurka/StructPacker +180)StructPacker https://github.com/RudolfKurka/StructPacker Why I have not put example: old ISourceGenerator -182)Svg https://github.com/wieslawsoltes/Svg.Skia +181)Svg https://github.com/wieslawsoltes/Svg.Skia Why I have not put example: old ISourceGenerator -183)tecli https://github.com/tyevco/TeCLI +182)tecli https://github.com/tyevco/TeCLI Why I have not put example: old ISourceGenerator -184)TeuJson https://github.com/Terria-K/TeuJson +183)TeuJson https://github.com/Terria-K/TeuJson Why I have not put example: json a class, was done in System.Text.Json -185)Thunderboltloc https://github.com/AlyElhaddad/ThunderboltIoc +184)Thunderboltloc https://github.com/AlyElhaddad/ThunderboltIoc Why I have not put example: old ISourceGenerator -186)Tinyhand https://github.com/archi-Doc/Tinyhand +185)Tinyhand https://github.com/archi-Doc/Tinyhand Why I have not put example: tried, need documentation -187)ToString https://github.com/Burgyn/MMLib.ToString +186)ToString https://github.com/Burgyn/MMLib.ToString Why I have not put example: old ISourceGenerator -188)Transplator https://github.com/atifaziz/Transplator +187)Transplator https://github.com/atifaziz/Transplator Why I have not put example: old ISourceGenerator -189)TupleOverloadGenerator https://github.com/ProphetLamb/TupleOverloadGenerator +188)TupleOverloadGenerator https://github.com/ProphetLamb/TupleOverloadGenerator Why I have not put example: too complicated -190)TxtToListGenerator https://github.com/musictopia2/TxtToListGenerator +189)TxtToListGenerator https://github.com/musictopia2/TxtToListGenerator Why I have not put example: no readme -191)TypealizR https://github.com/earloc/TypealizR +190)TypealizR https://github.com/earloc/TypealizR Why I have not put example: depends on Microsoft.Extensions.Localization -192)UnitTestBlazor https://github.com/bUnit-dev/bUnit +191)UnitTestBlazor https://github.com/bUnit-dev/bUnit Why I have not put example: issue opened -193)ValueChangedGenerator https://github.com/ufcpp/ValueChangedGenerator +192)ValueChangedGenerator https://github.com/ufcpp/ValueChangedGenerator Why I have not put example: old ISourceGenerator -194)ValueLink https://github.com/archi-Doc/ValueLink +193)ValueLink https://github.com/archi-Doc/ValueLink Why I have not put example: too complicated -195)ValueObjectGenerator https://github.com/RyotaMurohoshi/ValueObjectGenerator +194)ValueObjectGenerator https://github.com/RyotaMurohoshi/ValueObjectGenerator Why I have not put example: old ISourceGenerator -196)VisitorPatternGenerator https://github.com/hikarin522/VisitorPatternGenerator/ +195)VisitorPatternGenerator https://github.com/hikarin522/VisitorPatternGenerator/ Why I have not put example: issue opened -197)Visor https://github.com/Tinkoff/Visor +196)Visor https://github.com/Tinkoff/Visor Why I have not put example: archived -198)WrapperValueObject https://github.com/martinothamar/WrapperValueObject +197)WrapperValueObject https://github.com/martinothamar/WrapperValueObject Why I have not put example: not maintained as in readme -199)Xtz.StronglyTyped https://github.com/dev-experience/Xtz.StronglyTyped +198)Xtz.StronglyTyped https://github.com/dev-experience/Xtz.StronglyTyped Why I have not put example: old ISourceGenerator diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/ErrorOrX.md b/v2/rscg_examples_site/docs/RSCG-Examples/ErrorOrX.md new file mode 100644 index 000000000..c465edcd2 --- /dev/null +++ b/v2/rscg_examples_site/docs/RSCG-Examples/ErrorOrX.md @@ -0,0 +1,1205 @@ +--- +sidebar_position: 2540 +title: 254 - ErrorOrX +description: API results from Functional returns of ErroOrX +slug: /ErrorOrX +--- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import TOCInline from '@theme/TOCInline'; +import SameCategory from '../Categories/_PrimitiveAPI.mdx'; + +# ErrorOrX by Alexander Nachtmanns + + + + +## NuGet / site data +[![Nuget](https://img.shields.io/nuget/dt/ErrorOrX?label=ErrorOrX)](https://www.nuget.org/packages/ErrorOrX/) +[![GitHub last commit](https://img.shields.io/github/last-commit/ANcpLua/ErrorOrX?label=updated)](https://github.com/ANcpLua/ErrorOrX) +![GitHub Repo stars](https://img.shields.io/github/stars/ANcpLua/ErrorOrX?style=social) + +## Details + +### Info +:::info + +Name: **ErrorOrX** + +A discriminated union type for .NET with source-generated ASP.NET Core Minimal API integration. Zero boilerplate, full AOT support. + +Author: Alexander Nachtmanns + +NuGet: +*https://www.nuget.org/packages/ErrorOrX/* + + +You can find more details at https://github.com/ANcpLua/ErrorOrX + +Source: https://github.com/ANcpLua/ErrorOrX + +::: + +### Author +:::note +Alexander Nachtmanns +![Alt text](https://github.com/ANcpLua.png) +::: + +### Original Readme +:::note + +# ErrorOrX + +[![NuGet](https://img.shields.io/nuget/v/ErrorOrX.Generators.svg)](https://www.nuget.org/packages/ErrorOrX.Generators/) +[![NuGet Downloads](https://img.shields.io/nuget/dt/ErrorOrX.Generators.svg)](https://www.nuget.org/packages/ErrorOrX.Generators/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +Railway-Oriented Programming for .NET with source-generated ASP.NET Core Minimal API integration. Zero boilerplate, full +Native AOT support. + +## Features + +- **Discriminated Unions** - `ErrorOr` represents success or a list of typed errors +- **Fluent API** - Chain operations with `Then`, `Else`, `Match`, `Switch`, and `FailIf` +- **Nullable Extensions** - Convert nullable values with `OrNotFound()`, `OrValidation()`, and more +- **Source Generator** - Auto-generates `MapErrorOrEndpoints()` from attributed static methods +- **Smart Binding** - Automatic parameter inference based on HTTP method and type +- **OpenAPI Ready** - Typed `Results<...>` unions for complete API documentation +- **Native AOT** - Reflection-free code generation with JSON serialization contexts +- **Middleware Support** - Translates ASP.NET Core attributes to Minimal API fluent calls (authorization, rate limiting, + caching) +- **API Versioning** - Integrates with Asp.Versioning.Http for versioned endpoint groups +- **41 Analyzers** - Real-time IDE feedback for route conflicts, binding errors, AOT compatibility + +## What the Generator Produces + +The source generator transforms your handler methods into complete ASP.NET Core Minimal API endpoints. +You write the business logic, the generator handles everything else. + +### Endpoint Wiring + +For each `[Get]`, `[Post]`, `[Put]`, `[Delete]`, `[Patch]` method: + +- Registers endpoint with `app.MapGet()`, `app.MapPost()`, etc. +- Applies route constraints (`{id:guid}`, `{count:int}`) +- Sets operation name (`.WithName()`) and tags (`.WithTags()`) + +[See EndpointMetadataEmitter.cs](https://github.com/ANcpLua/ErrorOrX/src/ErrorOrX.Generators/Emitters/EndpointMetadataEmitter.cs) + +### Parameter Binding + +Automatic inference based on type and HTTP method: + +| Source | Inference Rule | +|---------|-----------------------------------------------------------------------| +| Route | Parameter name matches `{param}` in route | +| Query | Primitive type not in route | +| Body | POST/PUT/PATCH with complex type | +| Service | Interface, abstract, or DI naming pattern (`*Service`, `*Repository`) | +| Special | `HttpContext`, `CancellationToken`, `IFormFile` | + +[See BindingCodeEmitter.cs](https://github.com/ANcpLua/ErrorOrX/src/ErrorOrX.Generators/Emitters/BindingCodeEmitter.cs) + +### Error-to-HTTP Mapping + +Converts `ErrorOr` errors to proper HTTP responses with [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) +ProblemDetails: + +| ErrorType | HTTP Status | Response | +|--------------|-------------|---------------------------------------| +| Validation | 400 | `ValidationProblem` with field errors | +| Unauthorized | 401 | `Unauthorized()` | +| Forbidden | 403 | `Forbid()` | +| NotFound | 404 | `NotFound` | +| Conflict | 409 | `Conflict` | +| Failure | 500 | `InternalServerError` | +| Unexpected | 500 | `InternalServerError` | +| Custom(422) | 422 | `UnprocessableEntity` | + +[See ErrorMapping.cs](https://github.com/ANcpLua/ErrorOrX/src/ErrorOrX.Generators/Models/ErrorMapping.cs) + +### Request Validation + +Generated code validates before calling your handler: + +- Required parameters (returns 400 if missing) +- Type parsing (Guid, int, etc. with format errors) +- JSON deserialization (catches `JsonException`) +- Content-Type checking (returns 415 for wrong type) + +### OpenAPI Metadata + +Full OpenAPI documentation without manual attributes: + +- Response types via `ProducesResponseTypeMetadata` +- Accept types via `AcceptsMetadata` +- Tags from class name +- Operation IDs from method name +- XML doc comments extracted to summaries + +[See OpenApiTransformerGenerator.cs](https://github.com/ANcpLua/ErrorOrX/src/ErrorOrX.Generators/OpenApiTransformerGenerator.cs) + +### Builder API + +Fluent configuration following ASP.NET Core patterns: + +```csharp +builder.Services.AddErrorOrEndpoints() + .UseJsonContext() // AOT JSON + .WithCamelCase() // Property naming + .WithIgnoreNulls(); // Skip null values + +app.MapErrorOrEndpoints() + .RequireAuthorization() // Global auth + .RequireRateLimiting("api"); // Global rate limit +``` + +### Analyzers (38 Diagnostics) + +Real-time IDE feedback covering: + +| Category | Diagnostics | Examples | +|------------|-------------|----------------------------------------------------------------------| +| Core | EOE001-007 | Invalid return type, non-static handler, unbound route param | +| Binding | EOE008-021 | Multiple body sources, invalid `[FromRoute]` type, ambiguous binding | +| Results | EOE022-024 | Too many result types, unknown error factory, undocumented interface | +| AOT/JSON | EOE025-026 | Missing camelCase, missing JsonSerializerContext | +| Versioning | EOE027-031 | Version-neutral conflict, undeclared version, invalid format | +| Naming | EOE032-033 | Duplicate route binding, non-PascalCase handler | +| AOT Safety | EOE034-038 | `Activator.CreateInstance`, `dynamic`, `Expression.Compile()` | + +[See Descriptors.cs](https://github.com/ANcpLua/ErrorOrX/src/ErrorOrX.Generators/Analyzers/Descriptors.cs) + +## Installation + +```bash +dotnet add package ErrorOrX.Generators +``` + +This package includes both the source generator and the `ErrorOrX` runtime library. + +## Quick Start + +```csharp +// Program.cs +var app = WebApplication.CreateSlimBuilder(args).Build(); +app.MapErrorOrEndpoints(); +app.Run(); +``` + +```csharp +// TodoApi.cs +using ErrorOr; + +public static class TodoApi +{ + [Get("/todos/{id:guid}")] + public static ErrorOr GetById(Guid id, ITodoService svc) + => svc.GetById(id).OrNotFound($"Todo {id} not found"); + + [Post("/todos")] + public static ErrorOr Create(CreateTodoRequest req, ITodoService svc) + => svc.Create(req); // 201 Created + + [Delete("/todos/{id:guid}")] + public static ErrorOr Delete(Guid id, ITodoService svc) + => svc.Delete(id) ? Result.Deleted : Error.NotFound(); +} +``` + +## Error Types + +Create structured errors mapped to HTTP status codes: + +```csharp +Error.Validation("User.InvalidEmail", "Email format is invalid") // 400 +Error.Unauthorized("Auth.InvalidToken", "Token has expired") // 401 +Error.Forbidden("Auth.InsufficientRole", "Admin role required") // 403 +Error.NotFound("User.NotFound", "User does not exist") // 404 +Error.Conflict("User.Duplicate", "Email already registered") // 409 +Error.Failure("Db.ConnectionFailed", "Database unavailable") // 500 +Error.Unexpected("Unknown", "An unexpected error occurred") // 500 +Error.Custom(422, "Validation.Complex", "Complex validation failed") +``` + +## Nullable-to-ErrorOr Extensions + +Convert nullable values to `ErrorOr` with auto-generated error codes: + +```csharp +// Error code auto-generated from type name (e.g., "Todo.NotFound") +return _todos.Find(t => t.Id == id).OrNotFound($"Todo {id} not found"); +return user.OrUnauthorized("Invalid credentials"); +return record.OrValidation("Record is invalid"); + +// Custom errors +return value.OrError(Error.Custom(422, "Custom.Code", "Custom message")); +return value.OrError(() => BuildExpensiveError()); // Lazy evaluation +``` + +| Extension | Error Type | HTTP | Description | +|---------------------|--------------|------|--------------------------| +| `.OrNotFound()` | NotFound | 404 | Resource not found | +| `.OrValidation()` | Validation | 400 | Input validation failed | +| `.OrUnauthorized()` | Unauthorized | 401 | Authentication required | +| `.OrForbidden()` | Forbidden | 403 | Insufficient permissions | +| `.OrConflict()` | Conflict | 409 | State conflict | +| `.OrFailure()` | Failure | 500 | Operational failure | +| `.OrUnexpected()` | Unexpected | 500 | Unexpected error | +| `.OrError(Error)` | Any | Any | Custom error | +| `.OrError(Func)` | Any | Any | Lazy custom error | + +## Fluent API + +Chain operations using railway-oriented programming patterns: + +```csharp +// Chain operations - errors short-circuit the pipeline +var result = ValidateOrder(request) + .Then(order => ProcessPayment(order)) + .Then(order => CreateShipment(order)) + .FailIf(order => order.Total <= 0, Error.Validation("Order.InvalidTotal", "Total must be positive")); + +// Handle both cases +return result.Match( + order => Ok(order), + errors => BadRequest(errors.First().Description)); + +// Provide fallback on error +var user = GetUser(id).Else(errors => DefaultUser); + +// Side effects +GetUser(id).Switch( + user => Console.WriteLine($"Found: {user.Name}"), + errors => Logger.LogError(errors.First().Description)); +``` + +## Result Markers + +Use semantic markers for endpoints without response bodies: + +```csharp +Result.Success // 200 OK (no body) +Result.Created // 201 Created (no body) +Result.Updated // 204 No Content +Result.Deleted // 204 No Content +``` + +## Interface Types with `[ReturnsError]` + +Document possible errors on interface methods for OpenAPI generation: + +```csharp +public interface ITodoService +{ + [ReturnsError(ErrorType.NotFound, "Todo.NotFound")] + [ReturnsError(ErrorType.Validation, "Todo.Invalid")] + ErrorOr GetById(Guid id); +} + +[Get("/todos/{id:guid}")] +public static ErrorOr GetById(Guid id, ITodoService svc) => + svc.GetById(id); +// Generates: Results, NotFound, ValidationProblem> +``` + +The generator reads `[ReturnsError]` attributes from interface/abstract methods to build the complete `Results<...>` +union for OpenAPI documentation. + +## Smart Parameter Binding + +The generator automatically infers parameter sources: + +```csharp +[Post("/todos")] +public static ErrorOr Create( + CreateTodoRequest req, // -> Body (POST + complex type) + ITodoService svc) // -> Service (interface) + => svc.Create(req); + +[Get("/todos/{id:guid}")] +public static ErrorOr GetById( + Guid id, // -> Route (matches {id}) + ITodoService svc) // -> Service + => svc.GetById(id).OrNotFound(); +``` + +## Middleware Attributes + +Standard ASP.NET Core attributes on your handler methods are translated to Minimal API fluent calls: + +```csharp +[Post("/admin")] +[Authorize("Admin")] // ASP.NET Core authorization +[EnableRateLimiting("fixed")] // Microsoft.AspNetCore.RateLimiting +[OutputCache(Duration = 60)] // ASP.NET Core output caching +public static ErrorOr CreateAdmin(CreateUserRequest req) \{ } + +// Generator emits: +// app.MapPost("/admin", handler) +// .RequireAuthorization("Admin") +// .RequireRateLimiting("fixed") +// .CacheOutput(policy => policy.Expire(TimeSpan.FromSeconds(60))); +``` + +## Native AOT + +Fully compatible with `PublishAot=true`. Create a `JsonSerializerContext` with your endpoint types: + +```csharp +[JsonSourceGenerationOptions( + PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +[JsonSerializable(typeof(Todo))] +[JsonSerializable(typeof(CreateTodoRequest))] +[JsonSerializable(typeof(ProblemDetails))] +internal partial class AppJsonSerializerContext : JsonSerializerContext; +``` + +Register it with ErrorOrEndpoints: + +```csharp +var builder = WebApplication.CreateSlimBuilder(args); + +builder.Services.AddErrorOrEndpoints() + .UseJsonContext(); // Uses options from [JsonSourceGenerationOptions] + +var app = builder.Build(); +app.MapErrorOrEndpoints(); +app.Run(); +``` + +The `[JsonSourceGenerationOptions]` on your context controls serialization behavior (camelCase, null handling). +The builder methods `WithCamelCase()` and `WithIgnoreNulls()` are only needed if you want to override at runtime. + +## Packages + +| Package | Target | Description | +|-----------------------|------------------|--------------------------------------| +| `ErrorOrX.Generators` | `netstandard2.0` | Source generator (includes ErrorOrX) | +| `ErrorOrX` | `net10.0` | Runtime library (auto-referenced) | + +## Changelog + +See [CHANGELOG.md](https://github.com/ANcpLua/ErrorOrX/CHANGELOG.md) for version history. + + +::: + +### About +:::note + +API results from Functional returns of ErroOrX + + +::: + +## How to use + +### Example (source csproj, source files) + + + + + +This is the CSharp Project that references **ErrorOrX** +```xml showLineNumbers {10} + + + + net10.0 + enable + enable + + + + + + + + + + + true + $(BaseIntermediateOutputPath)\GX + + + +``` + + + + + + This is the use of **ErrorOrX** in *Program.cs* + +```csharp showLineNumbers +using OpenAPISwaggerUI; + +var builder = WebApplication.CreateBuilder(args); + +//instead of this +//builder.Services.AddOpenApi(); +builder.Services.AddErrorOrOpenApi(); +builder.Services.AddErrorOrEndpoints(); +var app = builder.Build(); + +// Configure the HTTP request pipeline. +//if (app.Environment.IsDevelopment()) +{ + app.MapOpenApi(); + app.UseOpenAPISwaggerUI(); +} +app.MapErrorOrEndpoints(); +//app.UseHttpsRedirection(); + +var summaries = new[] +{ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" +}; + +app.MapGet("/weatherforecast", () => +{ + var forecast = Enumerable.Range(1, 5).Select(index => + new WeatherForecast + ( + DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + Random.Shared.Next(-20, 55), + summaries[Random.Shared.Next(summaries.Length)] + )) + .ToArray(); + return forecast; +}) +.WithName("GetWeatherForecast"); + +app.Run(); + +internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) +{ + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); +} + +``` + + + + + This is the use of **ErrorOrX** in *PersonAPI.cs* + +```csharp showLineNumbers +using ErrorOr; + +namespace DemoFuncAPI; + +public static class PersonAPI +{ + + [Get("/todos/{id}")] + public static ErrorOr GetById(int id) + { + try + { + return GetPersonById(id).OrNotFound(); + } + catch (Exception ex) + { + return Error.Failure(description: ex.Message); + } + } + + static Person? GetPersonById(int id) => + + id switch + { + 1 => new Person(1, "John Doe"), + 2 => throw new Exception("person does not exists"), + _ => null + }; + +} + +public record Person(int Id, string Name) ; + +``` + + + + +### Generated Files + +Those are taken from $(BaseIntermediateOutputPath)\GX + + + + +```csharp showLineNumbers +// +#nullable enable + +namespace ErrorOr +{ + /// + /// Marks a static method as an ErrorOr endpoint with explicit HTTP method and route. + /// Prefer using [Get], [Post], [Put], [Delete], or [Patch] for standard HTTP methods. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false)] + public sealed class ErrorOrEndpointAttribute : global::System.Attribute + { + public ErrorOrEndpointAttribute(string httpMethod, string route) + { + HttpMethod = httpMethod; + Route = route; + } + public string HttpMethod \{ get; } + public string Route \{ get; } + } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false)] + public sealed class GetAttribute : global::System.Attribute + { + public GetAttribute(string route) => Route = route; + public string Route \{ get; } + } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false)] + public sealed class PostAttribute : global::System.Attribute + { + public PostAttribute(string route) => Route = route; + public string Route \{ get; } + } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false)] + public sealed class PutAttribute : global::System.Attribute + { + public PutAttribute(string route) => Route = route; + public string Route \{ get; } + } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false)] + public sealed class DeleteAttribute : global::System.Attribute + { + public DeleteAttribute(string route) => Route = route; + public string Route \{ get; } + } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false)] + public sealed class PatchAttribute : global::System.Attribute + { + public PatchAttribute(string route) => Route = route; + public string Route \{ get; } + } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)] + public sealed class ProducesErrorAttribute : global::System.Attribute + { + public ProducesErrorAttribute(int statusCode, string errorType) + { + StatusCode = statusCode; + ErrorType = errorType; + } + public int StatusCode \{ get; } + public string ErrorType \{ get; } + } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false)] + public sealed class AcceptedResponseAttribute : global::System.Attribute \{ } + + [global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = true)] + public sealed class ReturnsErrorAttribute : global::System.Attribute + { + public ReturnsErrorAttribute(global::ErrorOr.ErrorType errorType, string errorCode) + { + ErrorType = errorType; + ErrorCode = errorCode; + } + public ReturnsErrorAttribute(int statusCode, string errorCode) + { + StatusCode = statusCode; + ErrorCode = errorCode; + ErrorType = null; + } + public global::ErrorOr.ErrorType? ErrorType \{ get; } + public int? StatusCode \{ get; } + public string ErrorCode \{ get; } + } + + /// + /// Marks a class as a route group for versioned API endpoints. + /// All endpoints in the class will be mapped under the specified path prefix + /// using the eShop-style NewVersionedApi() pattern when combined with [ApiVersion]. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Class, AllowMultiple = false)] + public sealed class RouteGroupAttribute : global::System.Attribute + { + public RouteGroupAttribute(string path) => Path = path; + public string Path \{ get; } + public string? ApiName \{ get; set; } + } +} +``` + + + + +```csharp showLineNumbers +// +// This file was auto-generated by ErrorOr.Generators. +// Do not modify this file directly. + +#nullable enable +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; + +namespace ErrorOr.Generated +{ + /// + /// Generated endpoint mappings for all [ErrorOrEndpoint] handlers in this assembly. + /// + public static class ErrorOrEndpointMappings + { + /// + /// Maps all ErrorOr endpoints to the application's routing table. + /// + /// The endpoint route builder to add mappings to. + /// A convention builder for applying global conventions to all endpoints. + /// + /// Thrown when AddErrorOrEndpoints() was not called during service registration. + /// + /// + /// This follows ASP.NET Core's convention builder pattern, enabling global + /// endpoint configuration like RequireAuthorization() or RequireRateLimiting(). + /// + /// + /// + /// app.MapErrorOrEndpoints() + /// .RequireAuthorization() + /// .RequireRateLimiting("api"); + /// + /// + public static IEndpointConventionBuilder MapErrorOrEndpoints(this IEndpointRouteBuilder app) + { + // Validate that AddErrorOrEndpoints() was called + var marker = app.ServiceProvider.GetService(); + if (marker is null) + { + throw new InvalidOperationException( + "Unable to find the required services. " + + "Please add all the required services by calling 'IServiceCollection.AddErrorOrEndpoints()' " + + "in the application startup code."); + } + + var __endpointBuilders = new System.Collections.Generic.List(); + + // GET /todos/{id} -> global::DemoFuncAPI.PersonAPI.GetById + var __ep0 = app.MapGet(@"/todos/{id}", (Delegate)Invoke_Ep0) + .WithName("DemoFuncAPI_PersonAPI_GetById") + .WithTags("PersonAPI") + .WithMetadata(new global::Microsoft.AspNetCore.Http.ProducesResponseTypeMetadata(200, typeof(global::DemoFuncAPI.Person), new[] \{ "application/json" })) + .WithMetadata(new global::Microsoft.AspNetCore.Http.ProducesResponseTypeMetadata(400, typeof(global::Microsoft.AspNetCore.Http.HttpValidationProblemDetails), new[] \{ "application/problem+json" })) + .WithMetadata(new global::Microsoft.AspNetCore.Http.ProducesResponseTypeMetadata(500, typeof(global::Microsoft.AspNetCore.Mvc.ProblemDetails), new[] \{ "application/problem+json" })) + ; + __endpointBuilders.Add(__ep0); + + + return new CompositeEndpointConventionBuilder(__endpointBuilders); + } + + /// + /// Registers ErrorOr endpoint services and returns a builder for configuration. + /// + /// The service collection to configure. + /// A builder for further configuration. + /// + /// This follows ASP.NET Core's builder pattern (like AddRazorComponents()) + /// enabling fluent extension method chaining without callback nesting. + /// + /// + /// + /// builder.Services.AddErrorOrEndpoints() + /// .UseJsonContext<AppJsonSerializerContext>() + /// .WithCamelCase() + /// .WithIgnoreNulls(); + /// + /// + public static IErrorOrEndpointsBuilder AddErrorOrEndpoints(this IServiceCollection services) + { + // Register marker service for validation in MapErrorOrEndpoints() + services.AddSingleton(); + return new ErrorOrEndpointsBuilder(services); + } + + private static async Task, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>> Invoke_Ep0(HttpContext ctx) + { + return await Invoke_Ep0_Core(ctx); + } + + private static Task, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>> Invoke_Ep0_Core(HttpContext ctx) + { + static global::Microsoft.AspNetCore.Mvc.ProblemDetails CreateBindProblem(string param, string reason) => new() + { + Title = "Bad Request", + Detail = $"Parameter '{param}' {reason}.", + Status = 400, + Type = "https://httpstatuses.io/400", + }; + + static Task, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>> BindFail(string param, string reason) + => Task.FromResult, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>>(global::Microsoft.AspNetCore.Http.TypedResults.BadRequest(CreateBindProblem(param, reason))); + + if (!TryGetRouteValue(ctx, "id", out var p0Raw) || !int.TryParse(p0Raw, out var p0)) return BindFail("id", "has invalid format"); + var result = global::DemoFuncAPI.PersonAPI.GetById(p0); + if (result.IsError) + { + if (result.Errors.Count is 0) return Task.FromResult, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>>(global::Microsoft.AspNetCore.Http.TypedResults.InternalServerError(new global::Microsoft.AspNetCore.Mvc.ProblemDetails \{ Title = "Error", Detail = "An error occurred but no details were provided.", Status = 500 })); + var first = result.Errors[0]; + var problem = new global::Microsoft.AspNetCore.Mvc.ProblemDetails + { + Title = first.Code, + Detail = first.Description, + Status = first.Type switch \{ global::ErrorOr.ErrorType.Validation => 400, global::ErrorOr.ErrorType.Unauthorized => 401, global::ErrorOr.ErrorType.Forbidden => 403, global::ErrorOr.ErrorType.NotFound => 404, global::ErrorOr.ErrorType.Conflict => 409, global::ErrorOr.ErrorType.Failure => 500, global::ErrorOr.ErrorType.Unexpected => 500, _ => (int)first.Type is >= 100 and <= 599 ? (int)first.Type : 500 } + }; + problem.Type = $"https://httpstatuses.io/{problem.Status}"; + + switch (first.Type) + { + case global::ErrorOr.ErrorType.Failure: + return Task.FromResult, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>>(global::Microsoft.AspNetCore.Http.TypedResults.InternalServerError(problem)); + default: + return Task.FromResult, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>>(global::Microsoft.AspNetCore.Http.TypedResults.InternalServerError(problem)); + } + } + + return Task.FromResult, global::Microsoft.AspNetCore.Http.HttpResults.BadRequest, global::Microsoft.AspNetCore.Http.HttpResults.InternalServerError>>(global::Microsoft.AspNetCore.Http.TypedResults.Ok(result.Value)); + } + + private static bool TryGetRouteValue(HttpContext ctx, string name, out string? value) + { + if (!ctx.Request.RouteValues.TryGetValue(name, out var raw) || raw is null) \{ value = null; return false; } + value = raw.ToString(); return value is not null; + } + + private static bool TryGetQueryValue(HttpContext ctx, string name, out string? value) + { + if (!ctx.Request.Query.TryGetValue(name, out var raw) || raw.Count is 0) \{ value = null; return false; } + value = raw.ToString(); return value is not null; + } + + private static global::Microsoft.AspNetCore.Http.IResult ToProblem(global::System.Collections.Generic.IReadOnlyList errors) + { + if (errors.Count is 0) return global::Microsoft.AspNetCore.Http.TypedResults.Problem(); + var hasValidation = false; + for (var i = 0; i < errors.Count; i++) if (errors[i].Type == global::ErrorOr.ErrorType.Validation) \{ hasValidation = true; break; } + if (hasValidation) + { + var dict = new global::System.Collections.Generic.Dictionary(); + foreach (var e in errors) + { + if (e.Type != global::ErrorOr.ErrorType.Validation) continue; + if (!dict.TryGetValue(e.Code, out var existing)) + dict[e.Code] = new[] \{ e.Description }; + else + { + var arr = new string[existing.Length + 1]; + existing.CopyTo(arr, 0); + arr[existing.Length] = e.Description; + dict[e.Code] = arr; + } + } + return global::Microsoft.AspNetCore.Http.TypedResults.ValidationProblem(dict); + } + var first = errors[0]; + var problem = new global::Microsoft.AspNetCore.Mvc.ProblemDetails + { + Title = first.Code, + Detail = first.Description, + Status = first.Type switch \{ global::ErrorOr.ErrorType.Validation => 400, global::ErrorOr.ErrorType.Unauthorized => 401, global::ErrorOr.ErrorType.Forbidden => 403, global::ErrorOr.ErrorType.NotFound => 404, global::ErrorOr.ErrorType.Conflict => 409, global::ErrorOr.ErrorType.Failure => 500, global::ErrorOr.ErrorType.Unexpected => 500, _ => (int)first.Type is >= 100 and <= 599 ? (int)first.Type : 500 } + }; + problem.Type = $"https://httpstatuses.io/{problem.Status}"; + return problem.Status switch + { + 400 => global::Microsoft.AspNetCore.Http.TypedResults.BadRequest(problem), + 401 => global::Microsoft.AspNetCore.Http.TypedResults.Unauthorized(), + 403 => global::Microsoft.AspNetCore.Http.TypedResults.Forbid(), + 404 => global::Microsoft.AspNetCore.Http.TypedResults.NotFound(problem), + 409 => global::Microsoft.AspNetCore.Http.TypedResults.Conflict(problem), + 422 => global::Microsoft.AspNetCore.Http.TypedResults.UnprocessableEntity(problem), + 500 => global::Microsoft.AspNetCore.Http.TypedResults.InternalServerError(problem), + _ => global::Microsoft.AspNetCore.Http.TypedResults.Problem(detail: first.Description, statusCode: problem.Status ?? 500, title: first.Code, type: problem.Type) + }; + } + } +} + +``` + + + + +```csharp showLineNumbers +// +// This file was generated by ErrorOr.Generators source generator. +// + +#nullable enable + +namespace ErrorOr.Generated +{ + /// + /// Marker service to verify that AddErrorOrEndpoints() was called. + /// + /// + /// This follows the ASP.NET Core pattern used by RazorComponentsMarkerService + /// to provide clear error messages when the service registration is missing. + /// + internal sealed class ErrorOrEndpointsMarkerService \{ } + + /// + /// Builder interface for configuring ErrorOr endpoints. + /// + /// + /// This pattern follows ASP.NET Core's IRazorComponentsBuilder design, + /// enabling fluent extension method chaining without callback nesting. + /// + public interface IErrorOrEndpointsBuilder + { + /// + /// Gets the service collection being configured. + /// + global::Microsoft.Extensions.DependencyInjection.IServiceCollection Services \{ get; } + } + + /// + /// Default implementation of . + /// + internal sealed class ErrorOrEndpointsBuilder : IErrorOrEndpointsBuilder + { + public ErrorOrEndpointsBuilder(global::Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + Services = services; + } + + public global::Microsoft.Extensions.DependencyInjection.IServiceCollection Services \{ get; } + } + + /// + /// Extension methods for . + /// + public static class ErrorOrEndpointsBuilderExtensions + { + /// + /// Registers a JsonSerializerContext for AOT-compatible JSON serialization. + /// + /// The JsonSerializerContext type. + /// The builder instance. + /// The builder instance for chaining. + public static IErrorOrEndpointsBuilder UseJsonContext(this IErrorOrEndpointsBuilder builder) + where TContext : global::System.Text.Json.Serialization.JsonSerializerContext, new() + { + builder.Services.ConfigureHttpJsonOptions(options => + { + options.SerializerOptions.TypeInfoResolverChain.Insert(0, new TContext()); + }); + return builder; + } + + /// + /// Uses camelCase for JSON property names. + /// + /// The builder instance. + /// Whether to enable camelCase (default: true). + /// The builder instance for chaining. + public static IErrorOrEndpointsBuilder WithCamelCase(this IErrorOrEndpointsBuilder builder, bool enabled = true) + { + if (enabled) + { + builder.Services.ConfigureHttpJsonOptions(options => + { + options.SerializerOptions.PropertyNamingPolicy = global::System.Text.Json.JsonNamingPolicy.CamelCase; + }); + } + return builder; + } + + /// + /// Ignores null values when serializing JSON. + /// + /// The builder instance. + /// Whether to ignore nulls (default: true). + /// The builder instance for chaining. + public static IErrorOrEndpointsBuilder WithIgnoreNulls(this IErrorOrEndpointsBuilder builder, bool enabled = true) + { + if (enabled) + { + builder.Services.ConfigureHttpJsonOptions(options => + { + options.SerializerOptions.DefaultIgnoreCondition = global::System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull; + }); + } + return builder; + } + } + + /// + /// Composite convention builder that applies conventions to multiple endpoints. + /// + /// + /// This follows the ASP.NET Core pattern for applying global conventions + /// to all endpoints registered by MapErrorOrEndpoints(). + /// + internal sealed class CompositeEndpointConventionBuilder : global::Microsoft.AspNetCore.Builder.IEndpointConventionBuilder + { + private readonly global::System.Collections.Generic.List _builders; + + public CompositeEndpointConventionBuilder(global::System.Collections.Generic.List builders) + { + _builders = builders; + } + + public void Add(global::System.Action convention) + { + foreach (var builder in _builders) + { + builder.Add(convention); + } + } + + public void Finally(global::System.Action finallyConvention) + { + foreach (var builder in _builders) + { + builder.Finally(finallyConvention); + } + } + } +} +``` + + + + +```csharp showLineNumbers +// +global using ErrorOr.Generated; +``` + + + + +```csharp showLineNumbers +// +#nullable enable + +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.OpenApi; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.OpenApi; + +namespace ErrorOr.Generated; + +/// +/// Document transformer for tag: PersonAPI +/// Generated from: [ErrorOrEndpoint] attribute on *PersonAPIEndpoints class +/// +file sealed class Tag_PersonAPI_Transformer : IOpenApiDocumentTransformer +{ + public Task TransformAsync( + OpenApiDocument document, + OpenApiDocumentTransformerContext context, + CancellationToken cancellationToken) + { + document.Tags ??= new HashSet(); + document.Tags.Add(new OpenApiTag \{ Name = "PersonAPI" }); + return Task.CompletedTask; + } +} + +/// +/// Operation transformer that applies XML documentation and parameter definitions to operations. +/// Each entry is a strict 1:1 mapping from handler signature to operation metadata. +/// +file sealed class XmlDocOperationTransformer : IOpenApiOperationTransformer +{ + // Pre-computed metadata from XML docs (compile-time extraction) + private static readonly FrozenDictionary OperationDocs = + new Dictionary + { + }.ToFrozenDictionary(StringComparer.Ordinal); + + // Pre-computed parameter descriptions from XML tags + private static readonly FrozenDictionary> ParameterDocs = + new Dictionary> + { + }.ToFrozenDictionary(StringComparer.Ordinal); + + // Pre-computed parameter definitions from handler signatures + private static readonly FrozenDictionary ParameterDefs = + new Dictionary + { + ["DemoFuncAPI_PersonAPI_GetById"] = [("id", ParameterLocation.Path, true, JsonSchemaType.Integer, "int32")], + }.ToFrozenDictionary(StringComparer.Ordinal); + + public Task TransformAsync( + OpenApiOperation operation, + OpenApiOperationTransformerContext context, + CancellationToken cancellationToken) + { + string? operationId = null; + var metadata = context.Description.ActionDescriptor?.EndpointMetadata; + if (metadata is not null) + { + for (var i = 0; i < metadata.Count; i++) + { + if (metadata[i] is IEndpointNameMetadata nameMetadata) + { + operationId = nameMetadata.EndpointName; + break; + } + } + } + + if (operationId is null) + return Task.CompletedTask; + + // Apply summary and description + if (OperationDocs.TryGetValue(operationId, out var docs)) + { + if (docs.Summary is not null) + operation.Summary ??= docs.Summary; + if (docs.Description is not null) + operation.Description ??= docs.Description; + } + + // Add parameter definitions from handler signatures + if (ParameterDefs.TryGetValue(operationId, out var paramDefs)) + { + operation.Parameters ??= []; + foreach (var (pName, pLocation, pRequired, pSchemaType, pSchemaFormat) in paramDefs) + { + var schema = new OpenApiSchema \{ Type = pSchemaType }; + if (pSchemaFormat is not null) schema.Format = pSchemaFormat; + operation.Parameters.Add(new OpenApiParameter + { + Name = pName, + In = pLocation, + Required = pRequired, + Schema = schema + }); + } + } + + // Apply parameter descriptions + if (ParameterDocs.TryGetValue(operationId, out var paramDocs) && operation.Parameters is not null) + { + foreach (var param in operation.Parameters) + { + if (param.Name is not null && paramDocs.TryGetValue(param.Name, out var paramDesc)) + { + param.Description ??= paramDesc; + } + } + } + + return Task.CompletedTask; + } +} + +/// +/// Schema transformer that applies type XML documentation to schemas. +/// Each entry is a strict 1:1 mapping from XML doc to schema description. +/// AOT-safe: Uses Type as dictionary key (no runtime reflection). +/// +file sealed class XmlDocSchemaTransformer : IOpenApiSchemaTransformer +{ + // Pre-computed type descriptions from XML docs (AOT-safe: Type keys resolved at compile-time) + private static readonly FrozenDictionary TypeDescriptions = + new Dictionary + { + [typeof(global::ErrorOr.ErrorOrEndpointAttribute)] = "Marks a static method as an ErrorOr endpoint with explicit HTTP method and route. Prefer using [Get], [Post], [Put], [Delete], or [Patch] for standard HTTP methods.", + [typeof(global::ErrorOr.RouteGroupAttribute)] = "Marks a class as a route group for versioned API endpoints. All endpoints in the class will be mapped under the specified path prefix using the eShop-style NewVersionedApi() pattern when combined with [ApiVersion].", + }.ToFrozenDictionary(); + + public Task TransformAsync( + OpenApiSchema schema, + OpenApiSchemaTransformerContext context, + CancellationToken cancellationToken) + { + var type = context.JsonTypeInfo.Type; + // For generic types, lookup the generic type definition + var lookupType = type.IsGenericType ? type.GetGenericTypeDefinition() : type; + if (TypeDescriptions.TryGetValue(lookupType, out var description)) + { + schema.Description ??= description; + } + return Task.CompletedTask; + } +} + +/// +/// Extension methods for registering generated OpenAPI transformers. +/// +public static class GeneratedOpenApiExtensions +{ + /// + /// Adds OpenAPI with generated transformers for ErrorOr endpoints. + /// Each transformer is registered following the strict 1:1 mapping rule. + /// + public static IServiceCollection AddErrorOrOpenApi( + this IServiceCollection services, + string documentName = "v1") + { + services.AddOpenApi(documentName, options => + { + // Tag: PersonAPI + options.AddDocumentTransformer(new Tag_PersonAPI_Transformer()); + + // XML doc summaries → operation metadata + options.AddOperationTransformer(new XmlDocOperationTransformer()); + + // XML doc summaries → schema descriptions + options.AddSchemaTransformer(new XmlDocSchemaTransformer()); + }); + + return services; + } +} + +``` + + + + +## Useful + +### Download Example (.NET C#) + +:::tip + +[Download Example project ErrorOrX ](/sources/ErrorOrX.zip) + +::: + + +### Share ErrorOrX + + + +https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX + + + diff --git a/v2/rscg_examples_site/docs/RSCG-Examples/index.md b/v2/rscg_examples_site/docs/RSCG-Examples/index.md index 2663acde9..7f645cfd2 100644 --- a/v2/rscg_examples_site/docs/RSCG-Examples/index.md +++ b/v2/rscg_examples_site/docs/RSCG-Examples/index.md @@ -1,7 +1,7 @@ --- sidebar_position: 30 -title: 253 RSCG list by category -description: 253 RSCG list by category +title: 254 RSCG list by category +description: 254 RSCG list by category slug: /rscg-examples --- @@ -49,7 +49,7 @@ import DocCardList from '@theme/DocCardList'; ## API
- Expand API =>examples:11 + Expand API =>examples:12 @@ -105,6 +105,11 @@ import DocCardList from '@theme/DocCardList'; [XmlCommentGenerator](/docs/XmlCommentGenerator) + + + +[ErrorOrX](/docs/ErrorOrX) +
@@ -1623,6 +1628,8 @@ flowchart LR; API--> XmlCommentGenerator((XmlCommentGenerator)) + API--> ErrorOrX((ErrorOrX)) + Async--> HsuSgSync((HsuSgSync)) Async--> AsyncIt((AsyncIt)) diff --git a/v2/rscg_examples_site/docs/about.md b/v2/rscg_examples_site/docs/about.md index 25af1865e..4ad1df422 100644 --- a/v2/rscg_examples_site/docs/about.md +++ b/v2/rscg_examples_site/docs/about.md @@ -6,7 +6,7 @@ title: About ## Content You will find here code examples -of 253 Roslyn Source Code Generator (RSCG) +of 254 Roslyn Source Code Generator (RSCG) that can be useful for you. That means, you will write more elegant and concise code - even if the generators code is not always nice to look. ## Are those examples ready for production? diff --git a/v2/rscg_examples_site/docs/indexRSCG.md b/v2/rscg_examples_site/docs/indexRSCG.md index 34d20eb15..16f185bd3 100644 --- a/v2/rscg_examples_site/docs/indexRSCG.md +++ b/v2/rscg_examples_site/docs/indexRSCG.md @@ -7,9 +7,9 @@ slug: /List-of-RSCG import useBaseUrl from '@docusaurus/useBaseUrl'; -## 253 RSCG with examples in descending chronological order +## 254 RSCG with examples in descending chronological order -This is the list of 253 ( 16 from Microsoft) RSCG with examples +This is the list of 254 ( 16 from Microsoft) RSCG with examples [See by category](/docs/rscg-examples) [See as json](/exports/RSCG.json) [See as Excel](/exports/RSCG.xlsx) @@ -20,6 +20,7 @@ This is the list of 253 ( 16 from Microsoft) RSCG with examples | No | Name | Date | Category | | --------- | ----- | ---- | -------- | +|254| [ErrorOrX by Alexander Nachtmanns ](/docs/ErrorOrX)|2026-02-02 => 02 February 2026 | [API](/docs/Categories/API) | |253| [FastCloner by Matěj Štágl ](/docs/FastCloner)|2026-02-01 => 01 February 2026 | [Clone](/docs/Categories/Clone) | |252| [RSCG_idempotency by Ignat Andrei ](/docs/RSCG_idempotency)|2026-01-28 => 28 January 2026 | [Idempotency](/docs/Categories/Idempotency) | |251| [OrderedBuildersGenerator by Georgiy Petrov ](/docs/OrderedBuildersGenerator)|2025-12-18 => 18 December 2025 | [Builder](/docs/Categories/Builder) | diff --git a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js index 45e7e002d..7427a13c4 100644 --- a/v2/rscg_examples_site/src/components/HomepageFeatures/index.js +++ b/v2/rscg_examples_site/src/components/HomepageFeatures/index.js @@ -4,7 +4,7 @@ import styles from './styles.module.css'; const FeatureList = [ { -title: '253 Examples (16 from MSFT)', +title: '254 Examples (16 from MSFT)', Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <> diff --git a/v2/rscg_examples_site/static/exports/RSCG.json b/v2/rscg_examples_site/static/exports/RSCG.json index a925ba2f0..abef16315 100644 --- a/v2/rscg_examples_site/static/exports/RSCG.json +++ b/v2/rscg_examples_site/static/exports/RSCG.json @@ -2025,6 +2025,14 @@ "Source": "https://github.com/lofcz/FastCloner/", "Category": "Clone", "AddedOn": "2026-02-01T00:00:00" + }, + { + "Name": "ErrorOrX", + "Link": "https://ignatandrei.github.io/RSCG_Examples/v2/docs/ErrorOrX", + "NuGet": "https://www.nuget.org/packages/ErrorOrX/", + "Source": "https://github.com/ANcpLua/ErrorOrX", + "Category": "API", + "AddedOn": "2026-02-02T00:00:00" } ] } \ No newline at end of file diff --git a/v2/rscg_examples_site/static/exports/RSCG.xlsx b/v2/rscg_examples_site/static/exports/RSCG.xlsx index e7b85fa24..a590b312a 100644 Binary files a/v2/rscg_examples_site/static/exports/RSCG.xlsx and b/v2/rscg_examples_site/static/exports/RSCG.xlsx differ diff --git a/v2/rscg_examples_site/static/sources/ErrorOrX.zip b/v2/rscg_examples_site/static/sources/ErrorOrX.zip new file mode 100644 index 000000000..9d9ec5e1b Binary files /dev/null and b/v2/rscg_examples_site/static/sources/ErrorOrX.zip differ