Category: .NET

RSCG – Weave

RSCG – Weave
 
 

name Weave
nuget https://www.nuget.org/packages/Weave/
link https://github.com/otac0n/Weave
author John Gietzen

Scriban like generator

 

This is how you can use Weave .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
	</PropertyGroup>

	<ItemGroup>
	  <None Remove="MyDataT.weave" />
	</ItemGroup>
	<ItemGroup>
		<PackageReference Include="Weave" Version="2.1.0">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
	</ItemGroup>
	<ItemGroup>
	  <WeaveTemplate Include="MyDataT.weave">
	    
	  </WeaveTemplate>
	</ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>

</Project>


The code that you will use is


using WeaveDemo;

Person p = new()
{
FirstName = "Andrei", LastName = "Ignat" 
};


MyProject.Templates.RenderFizzBuzz(p, Console.Out);

StringWriter sw = new();
MyProject.Templates.RenderFizzBuzz(p, sw);
Console.WriteLine("---------------------------");
Console.WriteLine(sw.ToString());




namespace WeaveDemo;
internal class Person
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public string FullName() => $"{FirstName} {LastName}";
}


 

The code that is generated is

// -----------------------------------------------------------------------
// <auto-generated>
//   This code was generated by Weave 2.1.0.0
//
//   Changes to this file may cause incorrect behavior and will be lost if
//   the code is regenerated.
// </auto-generated>
// -----------------------------------------------------------------------

namespace
    #line 1 "..\..\..\MyDataT.weave"
           MyProject
    #line default
{
    using System;
    using System.IO;

    partial class
    Templates
    {
        [System.CodeDom.Compiler.GeneratedCode("Weave", "2.1.0.0")]
        public
        static void
        #line 2 "..\..\..\MyDataT.weave"
            RenderFizzBuzz
        #line default
            (
            #line 3 "..\..\..\MyDataT.weave"
       WeaveDemo.Person
            #line default
            model, TextWriter writer, string indentation = null)
        {
            var __originalIndentation = indentation = indentation ?? string.Empty;
            writer.Write(indentation);
            writer.Write("I will write p.FullName();");
            writer.WriteLine();
            writer.WriteLine();
            writer.Write(indentation);
            writer.Write(
                #line 7 "..\..\..\MyDataT.weave"
    model.FullName() 
                #line default
                );
            writer.WriteLine();
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Weave

RSCG – HangfireRecurringJob

RSCG – HangfireRecurringJob
 
 

name HangfireRecurringJob
nuget https://www.nuget.org/packages/IeuanWalker.Hangfire.RecurringJob/
link https://github.com/IeuanWalker/Hangfire.RecurringJob
author Ieuan Walker

Generating recurring jobs for Hangfire from class attribute

 

This is how you can use HangfireRecurringJob .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <InvariantGlobalization>true</InvariantGlobalization>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Hangfire.AspNetCore" Version="1.8.9" />
    <PackageReference Include="Hangfire.Core" Version="1.8.9" />
    <PackageReference Include="Hangfire.InMemory" Version="0.7.0" />
    <!--<PackageReference Include="Hangfire.MemoryStorage" Version="1.8.0" />-->
    <PackageReference Include="Hangfire.SqlServer" Version="1.8.9" />
    <PackageReference Include="IeuanWalker.Hangfire.RecurringJob" Version="1.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.1" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using IeuanWalker.Hangfire.RecurringJob.Attributes;

namespace HangFireRec;
[RecurringJob("*/1 * * * *")]
public class MyNewJob
{
    public async Task Execute()
    {
       await Task.Delay(1000);
        Console.WriteLine("Hello from recurring job hangfire");
    }
}



using Hangfire;
//using Hangfire.MemoryStorage;
using HangFireRec;
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHangfire(it =>
{
    it.UseInMemoryStorage();
    
});
builder.Services.AddHangfireServer(opt =>
{
    //config.UseMemoryStorage();
});
//GlobalConfiguration.Configuration.UseInMemoryStorage();
var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHangfireDashboard();
//app.UseHangfireServer();

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")
.WithOpenApi();
BackgroundJob.Enqueue(() =>Console.WriteLine("Hello from hangfire"));
RecurringJob.AddOrUpdate(() => Console.WriteLine("Hello from hangfire"), Cron.Minutely());
app.AddRecurringJobsFromHangFireRec();
app.Run();

internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}


 

The code that is generated is

namespace HangFireRec;

// <auto-generated/>

using Hangfire;
using Microsoft.AspNetCore.Builder;

public static class RecurringJobRegistrationExtensions
{
	public static IApplicationBuilder AddRecurringJobsFromHangFireRec(this IApplicationBuilder app)
	{
		RecurringJob.AddOrUpdate<HangFireRec.MyNewJob>("MyNewJob", "default", x => x.Execute(), "*/1 * * * *", new RecurringJobOptions
		{
			TimeZone = TimeZoneInfo.FindSystemTimeZoneById("UTC")
		});

		return app;
	}
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/HangfireRecurringJob

RSCG – Blazorators

RSCG – Blazorators
 
 

name Blazorators
nuget https://www.nuget.org/packages/Blazor.SourceGenerators/
link https://github.com/IEvangelist/blazorators/
author David Pine

Generate javascript interop code for Blazor WASM projects.

 

This is how you can use Blazorators .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.1" PrivateAssets="all" />
  </ItemGroup>

	<ItemGroup>
		<PackageReference Include="Blazor.Serialization" Version="8.0.0" />
		<PackageReference Include="Blazor.SourceGenerators"
						  Version="8.0.0"
						  OutputItemType="Analyzer"
						  SetTargetFramework="TargetFramework=netstandard2.0"
						  ReferenceOutputAssembly="false">
		</PackageReference>
	</ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>




The code that you will use is


using BlazorApp2;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddLocalStorageServices();

await builder.Build().RunAsync();



namespace BlazorApp2;

[JSAutoGenericInterop(
    TypeName = "Storage",
    Implementation = "window.localStorage",
    Url = "https://developer.mozilla.org/docs/Web/API/Window/localStorage",
    GenericMethodDescriptors = new[]
    {
        "getItem",
        "setItem:value"
    })]

public partial interface ILocalStorageService
{
}





@page "/"
@inject ILocalStorageService MyLocalStorage;

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Please refresh the page to see the value persisted in local storage.
@{
    var name = MyLocalStorage.GetItem<string>("name");
    if (name != null)
    {
        <p>Hi, @name</p>
    }
    else
    {
        <p>Hi, stranger</p>
    }
    MyLocalStorage.SetItem("name", "Andrei Ignat");
}


 

The code that is generated is

/// <summary>
/// The Blazor hosting model source, either WebAssembly or Server.
/// </summary>
public enum BlazorHostingModel
{
    /// <summary>
    /// This is the default. Use this to source generate targeting the synchronous <c>IJSInProcessRuntime</c> type.
    /// </summary>
    WebAssembly,

    /// <summary>
    /// Use this to source generate targeting the synchronous <c>IJSRuntime</c> type.
    /// </summary>
    Server
};

// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License:
// https://bit.ly/blazorators-license
// Auto-generated by blazorators.
using Blazor.Serialization.Extensions;
using System.Text.Json;

#nullable enable
namespace BlazorApp2;
/// <summary>
/// Source generated interface definition of the <c>Storage</c> type.
/// </summary>
public partial interface ILocalStorageService
{
    /// <summary>
    /// Source generated implementation of <c>window.localStorage.clear</c>.
    /// <a href="https://developer.mozilla.org/docs/Web/API/Storage/clear"></a>
    /// </summary>
    void Clear();
    /// <summary>
    /// Source generated implementation of <c>window.localStorage.getItem</c>.
    /// <a href="https://developer.mozilla.org/docs/Web/API/Storage/getItem"></a>
    /// </summary>
    TValue? GetItem<TValue>(string key, JsonSerializerOptions? options = null);
    /// <summary>
    /// Source generated implementation of <c>window.localStorage.key</c>.
    /// <a href="https://developer.mozilla.org/docs/Web/API/Storage/key"></a>
    /// </summary>
    string? Key(double index);
    /// <summary>
    /// Source generated implementation of <c>window.localStorage.removeItem</c>.
    /// <a href="https://developer.mozilla.org/docs/Web/API/Storage/removeItem"></a>
    /// </summary>
    void RemoveItem(string key);
    /// <summary>
    /// Source generated implementation of <c>window.localStorage.setItem</c>.
    /// <a href="https://developer.mozilla.org/docs/Web/API/Storage/setItem"></a>
    /// </summary>
    void SetItem<TValue>(string key, TValue value, JsonSerializerOptions? options = null);
    /// <summary>
    /// Source generated implementation of <c>window.localStorage.length</c>.
    /// <a href="https://developer.mozilla.org/docs/Web/API/Storage/length"></a>
    /// </summary>
    double Length { get; }
}
#nullable enable
/// <summary>
/// Use this attribute on <code>public static partial</code> extension method classes.
/// For example:
/// <example>
/// <code>
/// [JSAutoGenericInterop(
///    TypeName = "Storage",
///    Implementation = "window.localStorage",
///    HostingModel = BlazorHostingModel.WebAssembly,
///    Url = "https://developer.mozilla.org/docs/Web/API/Window/localStorage",
///    GenericMethodDescriptors = new[]
///    {
///        "getItem",
///        "setItem:value"
///    })]
/// public static partial LocalStorageExtensions
/// {
/// }
/// </code>
/// </example>
/// This will source generate all the extension methods for the IJSInProcessRuntime type for the localStorage APIs.
/// </summary>
public class JSAutoGenericInteropAttribute : JSAutoInteropAttribute
{
    /// <summary>
    /// The descriptors that define which APIs are to use default JSON serialization and support generics.
    /// For example:
    /// <code>
    /// new[]
    /// {
    ///     "getItem",      // Serializes the return type of getItem as TValue
    ///     "setItem:value" // Serializes the value parameter of the setItem TValue
    /// }
    /// </code>
    /// </summary>
    public string[] GenericMethodDescriptors { get; set; } = null!;

    /// <summary>
    /// The overrides that define which APIs to override (only applicable for pure JavaScript).
    /// For example:
    /// <code>
    /// new[]
    /// {
    ///     "getVoices",  // A pure JS method with by this name will have a custom impl.
    /// }
    /// </code>
    /// </summary>
    public string[] PureJavaScriptOverrides { get; set; } = null!;
}

#nullable enable
/// <summary>
/// Use this attribute on <code>public static partial</code> extension method classes.
/// For example:
/// <code>
/// [JSAutoInterop(
///    TypeName = "Storage",
///    Implementation = "window.localStorage",
///    HostingModel = BlazorHostingModel.WebAssembly,
///    Url = "https://developer.mozilla.org/docs/Web/API/Window/localStorage")]
/// public static partial LocalStorageExtensions
/// {
/// }
/// </code>
/// This will source generate all the extension methods for the IJSInProcessRuntime type for the localStorage APIs.
/// </summary>
[AttributeUsage(
    AttributeTargets.Interface,
    Inherited = false,
    AllowMultiple = false)]
public class JSAutoInteropAttribute : Attribute
{
    /// <summary>
    /// The type name that corresponds to the lib.dom.d.ts interface. For example, <c>"Geolocation"</c>.
    /// For more information, search 'interface {Name}'
    /// <a href='https://raw.githubusercontent.com/microsoft/TypeScript/main/lib/lib.dom.d.ts'>here for types</a>.
    /// </summary>
    public string TypeName { get; set; } = null!;

    /// <summary>
    /// The path from the <c>window</c> object to the corresponding <see cref="TypeName"/> implementation.
    /// For example, if the <see cref="TypeName"/> was <c>"Geolocation"</c>, this would be
    /// <c>"window.navigator.geolocation"</c> (or <c>"navigator.geolocation"</c>).
    /// </summary>
    public string Implementation { get; set; } = null!;

    /// <summary>
    /// Whether to generate only pure JavaScript functions that do not require callbacks.
    /// For example, <c>"Geolocation.clearWatch"</c> is consider pure, but <c>"Geolocation.watchPosition"</c> is not.
    /// Defaults to <c>true</c>.
    /// </summary>
    public bool OnlyGeneratePureJS { get; set; } = true;

    /// <summary>
    /// The Blazor hosting model to generate source for. WebAssembly creates <c>IJSInProcessRuntime</c> extensions,
    /// while Server creates <c>IJSRuntime</c> extensions. Defaults to <see cref="BlazorHostingModel.WebAssembly" />.
    /// </summary>
    public BlazorHostingModel HostingModel { get; set; } = BlazorHostingModel.WebAssembly;

    /// <summary>
    /// The optional URL to the corresponding API.
    /// </summary>
    public string? Url { get; set; }

    /// <summary>
    /// An optional array of TypeScript type declarations sources. Valid values are URLs or file paths.
    /// </summary>
    public string[]? TypeDeclarationSources { get; set; }
}

// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License:
// https://bit.ly/blazorators-license
// Auto-generated by blazorators.
using Blazor.Serialization.Extensions;
using System.Text.Json;

#nullable enable
namespace BlazorApp2;
/// <inheritdoc/>
internal sealed class LocalStorageService : ILocalStorageService
{
    internal readonly IJSInProcessRuntime _javaScript = null !;
    public LocalStorageService(IJSInProcessRuntime javaScript) => _javaScript = javaScript;
    /// <inheritdoc cref = "ILocalStorageService.Clear"/>
    void ILocalStorageService.Clear() => _javaScript.InvokeVoid("window.localStorage.clear");
    /// <inheritdoc cref = "ILocalStorageService.GetItem"/>
    TValue? ILocalStorageService.GetItem<TValue>(string key, JsonSerializerOptions? options)
        where TValue : default => _javaScript.Invoke<string?>("window.localStorage.getItem", key).FromJson<TValue>(options);
    /// <inheritdoc cref = "ILocalStorageService.Key"/>
    string? ILocalStorageService.Key(double index) => _javaScript.Invoke<string?>("window.localStorage.key", index);
    /// <inheritdoc cref = "ILocalStorageService.RemoveItem"/>
    void ILocalStorageService.RemoveItem(string key) => _javaScript.InvokeVoid("window.localStorage.removeItem", key);
    /// <inheritdoc cref = "ILocalStorageService.SetItem"/>
    void ILocalStorageService.SetItem<TValue>(string key, TValue value, JsonSerializerOptions? options) => _javaScript.InvokeVoid("window.localStorage.setItem", key, value.ToJson(options));
    /// <inheritdoc cref = "ILocalStorageService.Length"/>
    double ILocalStorageService.Length => _javaScript.Invoke<double>("eval", "window.localStorage.length");
}
// Copyright (c) David Pine. All rights reserved.
// Licensed under the MIT License:
// https://github.com/IEvangelist/blazorators/blob/main/LICENSE
// Auto-generated by blazorators.

using Microsoft.JSInterop;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary></summary>
public static class LocalStorageServiceCollectionExtensions
{
    /// <summary>
    /// Adds the <see cref="ILocalStorageService" /> service to the service collection.
    /// </summary>
    public static IServiceCollection AddLocalStorageServices(
        this IServiceCollection services) =>
        services.AddSingleton<IJSInProcessRuntime>(serviceProvider =>
            (IJSInProcessRuntime)serviceProvider.GetRequiredService<IJSRuntime>())
            .AddSingleton<ILocalStorageService, LocalStorageService>();
}

using System.ComponentModel;

namespace System.Runtime.CompilerServices
{
    [EditorBrowsable(EditorBrowsableState.Never)]
    internal class IsExternalInit { }
}
#pragma checksum "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\App.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "ca69fbc161c0130d6d7831728befc975abb17b04491a271bc49266261055543b"
// <auto-generated/>
#pragma warning disable 1591
namespace BlazorApp2
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http.Json;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web.Virtualization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.WebAssembly.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2.Layout;

#line default
#line hidden
#nullable disable
    public partial class App : global::Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenComponent<global::Microsoft.AspNetCore.Components.Routing.Router>(0);
            __builder.AddComponentParameter(1, "AppAssembly", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<global::System.Reflection.Assembly>(
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\App.razor"
                      typeof(App).Assembly

#line default
#line hidden
#nullable disable
            ));
            __builder.AddAttribute(2, "Found", (global::Microsoft.AspNetCore.Components.RenderFragment<Microsoft.AspNetCore.Components.RouteData>)((routeData) => (__builder2) => {
                __builder2.OpenComponent<global::Microsoft.AspNetCore.Components.RouteView>(3);
                __builder2.AddComponentParameter(4, "RouteData", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<global::Microsoft.AspNetCore.Components.RouteData>(
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\App.razor"
                               routeData

#line default
#line hidden
#nullable disable
                ));
                __builder2.AddComponentParameter(5, "DefaultLayout", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<global::System.Type>(
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\App.razor"
                                                          typeof(MainLayout)

#line default
#line hidden
#nullable disable
                ));
                __builder2.CloseComponent();
                __builder2.AddMarkupContent(6, "\r\n        ");
                __builder2.OpenComponent<global::Microsoft.AspNetCore.Components.Routing.FocusOnNavigate>(7);
                __builder2.AddComponentParameter(8, "RouteData", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<global::Microsoft.AspNetCore.Components.RouteData>(
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\App.razor"
                                     routeData

#line default
#line hidden
#nullable disable
                ));
                __builder2.AddComponentParameter(9, "Selector", "h1");
                __builder2.CloseComponent();
            }
            ));
            __builder.AddAttribute(10, "NotFound", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.OpenComponent<global::Microsoft.AspNetCore.Components.Web.PageTitle>(11);
                __builder2.AddAttribute(12, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder3) => {
                    __builder3.AddContent(13, "Not found");
                }
                ));
                __builder2.CloseComponent();
                __builder2.AddMarkupContent(14, "\r\n        ");
                __builder2.OpenComponent<global::Microsoft.AspNetCore.Components.LayoutView>(15);
                __builder2.AddComponentParameter(16, "Layout", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<global::System.Type>(
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\App.razor"
                             typeof(MainLayout)

#line default
#line hidden
#nullable disable
                ));
                __builder2.AddAttribute(17, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder3) => {
                    __builder3.AddMarkupContent(18, "<p role=\"alert\">Sorry, there\'s nothing at this address.</p>");
                }
                ));
                __builder2.CloseComponent();
            }
            ));
            __builder.CloseComponent();
        }
        #pragma warning restore 1998
    }
}
#pragma warning restore 1591

#pragma checksum "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\MainLayout.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "93d4b940f2ce228e270b07368e54f6d439ffc44bc31096274325558e65d2157f"
// <auto-generated/>
#pragma warning disable 1591
namespace BlazorApp2.Layout
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http.Json;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web.Virtualization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.WebAssembly.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2.Layout;

#line default
#line hidden
#nullable disable
    public partial class MainLayout : LayoutComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenElement(0, "div");
            __builder.AddAttribute(1, "class", "page");
            __builder.AddAttribute(2, "b-iwvdxzpj6w");
            __builder.OpenElement(3, "div");
            __builder.AddAttribute(4, "class", "sidebar");
            __builder.AddAttribute(5, "b-iwvdxzpj6w");
            __builder.OpenComponent<global::BlazorApp2.Layout.NavMenu>(6);
            __builder.CloseComponent();
            __builder.CloseElement();
            __builder.AddMarkupContent(7, "\r\n\r\n    ");
            __builder.OpenElement(8, "main");
            __builder.AddAttribute(9, "b-iwvdxzpj6w");
            __builder.AddMarkupContent(10, "<div class=\"top-row px-4\" b-iwvdxzpj6w><a href=\"https://learn.microsoft.com/aspnet/core/\" target=\"_blank\" b-iwvdxzpj6w>About</a></div>\r\n\r\n        ");
            __builder.OpenElement(11, "article");
            __builder.AddAttribute(12, "class", "content px-4");
            __builder.AddAttribute(13, "b-iwvdxzpj6w");
#nullable restore
#line (13,14)-(13,18) 25 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\MainLayout.razor"
__builder.AddContent(14, Body);

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.CloseElement();
            __builder.CloseElement();
        }
        #pragma warning restore 1998
    }
}
#pragma warning restore 1591

#pragma checksum "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\NavMenu.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "4ed23773930f65532bdb0b17b15ff5e805d3c4e59aad805d432503d0191cd0a9"
// <auto-generated/>
#pragma warning disable 1591
namespace BlazorApp2.Layout
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http.Json;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web.Virtualization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.WebAssembly.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2.Layout;

#line default
#line hidden
#nullable disable
    public partial class NavMenu : global::Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenElement(0, "div");
            __builder.AddAttribute(1, "class", "top-row ps-3 navbar navbar-dark");
            __builder.AddAttribute(2, "b-18uzve78me");
            __builder.OpenElement(3, "div");
            __builder.AddAttribute(4, "class", "container-fluid");
            __builder.AddAttribute(5, "b-18uzve78me");
            __builder.AddMarkupContent(6, "<a class=\"navbar-brand\" href b-18uzve78me>BlazorApp2</a>\r\n        ");
            __builder.OpenElement(7, "button");
            __builder.AddAttribute(8, "title", "Navigation menu");
            __builder.AddAttribute(9, "class", "navbar-toggler");
            __builder.AddAttribute(10, "onclick", global::Microsoft.AspNetCore.Components.EventCallback.Factory.Create<global::Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, 
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\NavMenu.razor"
                                                                         ToggleNavMenu

#line default
#line hidden
#nullable disable
            ));
            __builder.AddAttribute(11, "b-18uzve78me");
            __builder.AddMarkupContent(12, "<span class=\"navbar-toggler-icon\" b-18uzve78me></span>");
            __builder.CloseElement();
            __builder.CloseElement();
            __builder.CloseElement();
            __builder.AddMarkupContent(13, "\r\n\r\n");
            __builder.OpenElement(14, "div");
            __builder.AddAttribute(15, "class", (
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\NavMenu.razor"
             NavMenuCssClass

#line default
#line hidden
#nullable disable
            ) + " nav-scrollable");
            __builder.AddAttribute(16, "onclick", global::Microsoft.AspNetCore.Components.EventCallback.Factory.Create<global::Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, 
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\NavMenu.razor"
                                                       ToggleNavMenu

#line default
#line hidden
#nullable disable
            ));
            __builder.AddAttribute(17, "b-18uzve78me");
            __builder.OpenElement(18, "nav");
            __builder.AddAttribute(19, "class", "flex-column");
            __builder.AddAttribute(20, "b-18uzve78me");
            __builder.OpenElement(21, "div");
            __builder.AddAttribute(22, "class", "nav-item px-3");
            __builder.AddAttribute(23, "b-18uzve78me");
            __builder.OpenComponent<global::Microsoft.AspNetCore.Components.Routing.NavLink>(24);
            __builder.AddComponentParameter(25, "class", "nav-link");
            __builder.AddComponentParameter(26, "href", "");
            __builder.AddComponentParameter(27, "Match", global::Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<global::Microsoft.AspNetCore.Components.Routing.NavLinkMatch>(
#nullable restore
#line 13 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\NavMenu.razor"
                                                     NavLinkMatch.All

#line default
#line hidden
#nullable disable
            ));
            __builder.AddAttribute(28, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.AddMarkupContent(29, "<span class=\"bi bi-house-door-fill-nav-menu\" aria-hidden=\"true\" b-18uzve78me></span> Home\r\n            ");
            }
            ));
            __builder.CloseComponent();
            __builder.CloseElement();
            __builder.AddMarkupContent(30, "\r\n        ");
            __builder.OpenElement(31, "div");
            __builder.AddAttribute(32, "class", "nav-item px-3");
            __builder.AddAttribute(33, "b-18uzve78me");
            __builder.OpenComponent<global::Microsoft.AspNetCore.Components.Routing.NavLink>(34);
            __builder.AddComponentParameter(35, "class", "nav-link");
            __builder.AddComponentParameter(36, "href", "counter");
            __builder.AddAttribute(37, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.AddMarkupContent(38, "<span class=\"bi bi-plus-square-fill-nav-menu\" aria-hidden=\"true\" b-18uzve78me></span> Counter\r\n            ");
            }
            ));
            __builder.CloseComponent();
            __builder.CloseElement();
            __builder.AddMarkupContent(39, "\r\n        ");
            __builder.OpenElement(40, "div");
            __builder.AddAttribute(41, "class", "nav-item px-3");
            __builder.AddAttribute(42, "b-18uzve78me");
            __builder.OpenComponent<global::Microsoft.AspNetCore.Components.Routing.NavLink>(43);
            __builder.AddComponentParameter(44, "class", "nav-link");
            __builder.AddComponentParameter(45, "href", "weather");
            __builder.AddAttribute(46, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.AddMarkupContent(47, "<span class=\"bi bi-list-nested-nav-menu\" aria-hidden=\"true\" b-18uzve78me></span> Weather\r\n            ");
            }
            ));
            __builder.CloseComponent();
            __builder.CloseElement();
            __builder.CloseElement();
            __builder.CloseElement();
        }
        #pragma warning restore 1998
#nullable restore
#line 30 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Layout\NavMenu.razor"
       
    private bool collapseNavMenu = true;

    private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }

#line default
#line hidden
#nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Counter.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "886d5e15f1c63f4cc1caec7ff58936690cc18dd69931479d26471f7575854ec2"
// <auto-generated/>
#pragma warning disable 1591
namespace BlazorApp2.Pages
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http.Json;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web.Virtualization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.WebAssembly.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2.Layout;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Components.RouteAttribute("/counter")]
    public partial class Counter : global::Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenComponent<global::Microsoft.AspNetCore.Components.Web.PageTitle>(0);
            __builder.AddAttribute(1, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.AddContent(2, "Counter");
            }
            ));
            __builder.CloseComponent();
            __builder.AddMarkupContent(3, "\r\n\r\n");
            __builder.AddMarkupContent(4, "<h1>Counter</h1>\r\n\r\n");
            __builder.OpenElement(5, "p");
            __builder.AddAttribute(6, "role", "status");
            __builder.AddContent(7, "Current count: ");
#nullable restore
#line (7,34)-(7,46) 24 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Counter.razor"
__builder.AddContent(8, currentCount);

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.AddMarkupContent(9, "\r\n\r\n");
            __builder.OpenElement(10, "button");
            __builder.AddAttribute(11, "class", "btn btn-primary");
            __builder.AddAttribute(12, "onclick", global::Microsoft.AspNetCore.Components.EventCallback.Factory.Create<global::Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, 
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Counter.razor"
                                          IncrementCount

#line default
#line hidden
#nullable disable
            ));
            __builder.AddContent(13, "Click me");
            __builder.CloseElement();
        }
        #pragma warning restore 1998
#nullable restore
#line 11 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Counter.razor"
       
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }

#line default
#line hidden
#nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Home.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "3aa0919abc135f80e5cf81940d496935db1ecddffc2b0b077d38018b20b6d726"
// <auto-generated/>
#pragma warning disable 1591
namespace BlazorApp2.Pages
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http.Json;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web.Virtualization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.WebAssembly.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2.Layout;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Components.RouteAttribute("/")]
    public partial class Home : global::Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenComponent<global::Microsoft.AspNetCore.Components.Web.PageTitle>(0);
            __builder.AddAttribute(1, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.AddContent(2, "Home");
            }
            ));
            __builder.CloseComponent();
            __builder.AddMarkupContent(3, "\r\n\r\n");
            __builder.AddMarkupContent(4, "<h1>Hello, world!</h1>\r\n\r\nPlease refresh the page to see the value persisted in local storage.\r\n");
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Home.razor"
  
    var name = MyLocalStorage.GetItem<string>("name");
    if (name != null)
    {

#line default
#line hidden
#nullable disable
            __builder.OpenElement(5, "p");
            __builder.AddContent(6, "Hi, ");
#nullable restore
#line (13,17)-(13,21) 24 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Home.razor"
__builder.AddContent(7, name);

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
#nullable restore
#line 14 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Home.razor"
    }
    else
    {

#line default
#line hidden
#nullable disable
            __builder.AddMarkupContent(8, "<p>Hi, stranger</p>");
#nullable restore
#line 18 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Home.razor"
    }
    MyLocalStorage.SetItem("name", "Andrei Ignat");

#line default
#line hidden
#nullable disable
        }
        #pragma warning restore 1998
        [global::Microsoft.AspNetCore.Components.InjectAttribute] private ILocalStorageService MyLocalStorage { get; set; }
    }
}
#pragma warning restore 1591

#pragma checksum "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "91e0cba167af58d4c1dbd17785187574d7b8431106eb9fc9b48193bb1e109a61"
// <auto-generated/>
#pragma warning disable 1591
namespace BlazorApp2.Pages
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http.Json;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web.Virtualization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.WebAssembly.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2.Layout;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Components.RouteAttribute("/weather")]
    public partial class Weather : global::Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
            __builder.OpenComponent<global::Microsoft.AspNetCore.Components.Web.PageTitle>(0);
            __builder.AddAttribute(1, "ChildContent", (global::Microsoft.AspNetCore.Components.RenderFragment)((__builder2) => {
                __builder2.AddContent(2, "Weather");
            }
            ));
            __builder.CloseComponent();
            __builder.AddMarkupContent(3, "\r\n\r\n");
            __builder.AddMarkupContent(4, "<h1>Weather</h1>\r\n\r\n");
            __builder.AddMarkupContent(5, "<p>This component demonstrates fetching data from the server.</p>");
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
 if (forecasts == null)
{

#line default
#line hidden
#nullable disable
            __builder.AddMarkupContent(6, "<p><em>Loading...</em></p>");
#nullable restore
#line 13 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
}
else
{

#line default
#line hidden
#nullable disable
            __builder.OpenElement(7, "table");
            __builder.AddAttribute(8, "class", "table");
            __builder.AddMarkupContent(9, "<thead><tr><th>Date</th>\r\n                <th>Temp. (C)</th>\r\n                <th>Temp. (F)</th>\r\n                <th>Summary</th></tr></thead>\r\n        ");
            __builder.OpenElement(10, "tbody");
#nullable restore
#line 26 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
             foreach (var forecast in forecasts)
            {

#line default
#line hidden
#nullable disable
            __builder.OpenElement(11, "tr");
            __builder.OpenElement(12, "td");
#nullable restore
#line (29,26)-(29,59) 25 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
__builder.AddContent(13, forecast.Date.ToShortDateString());

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.AddMarkupContent(14, "\r\n                    ");
            __builder.OpenElement(15, "td");
#nullable restore
#line (30,26)-(30,47) 25 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
__builder.AddContent(16, forecast.TemperatureC);

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.AddMarkupContent(17, "\r\n                    ");
            __builder.OpenElement(18, "td");
#nullable restore
#line (31,26)-(31,47) 25 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
__builder.AddContent(19, forecast.TemperatureF);

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.AddMarkupContent(20, "\r\n                    ");
            __builder.OpenElement(21, "td");
#nullable restore
#line (32,26)-(32,42) 25 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
__builder.AddContent(22, forecast.Summary);

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.CloseElement();
#nullable restore
#line 34 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
            }

#line default
#line hidden
#nullable disable
            __builder.CloseElement();
            __builder.CloseElement();
#nullable restore
#line 37 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
}

#line default
#line hidden
#nullable disable
        }
        #pragma warning restore 1998
#nullable restore
#line 39 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\Pages\Weather.razor"
       
    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
    }

    public class WeatherForecast
    {
        public DateOnly Date { get; set; }

        public int TemperatureC { get; set; }

        public string? Summary { get; set; }

        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }

#line default
#line hidden
#nullable disable
        [global::Microsoft.AspNetCore.Components.InjectAttribute] private HttpClient Http { get; set; }
    }
}
#pragma warning restore 1591

#pragma checksum "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "d065d06a7544abc87a0d6ac6e4b47ca33ed0bc373f5ec7b85b2aa4d888f77d3e"
// <auto-generated/>
#pragma warning disable 1591
namespace BlazorApp2
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Components;
#nullable restore
#line 1 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using System.Net.Http.Json;

#line default
#line hidden
#nullable disable
#nullable restore
#line 3 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Forms;

#line default
#line hidden
#nullable disable
#nullable restore
#line 4 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Routing;

#line default
#line hidden
#nullable disable
#nullable restore
#line 5 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web;

#line default
#line hidden
#nullable disable
#nullable restore
#line 6 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.Web.Virtualization;

#line default
#line hidden
#nullable disable
#nullable restore
#line 7 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.AspNetCore.Components.WebAssembly.Http;

#line default
#line hidden
#nullable disable
#nullable restore
#line 8 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using Microsoft.JSInterop;

#line default
#line hidden
#nullable disable
#nullable restore
#line 9 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2;

#line default
#line hidden
#nullable disable
#nullable restore
#line 10 "C:\Users\ignat\Downloads\BlazorAppFullRef1\BlazorApp2\_Imports.razor"
using BlazorApp2.Layout;

#line default
#line hidden
#nullable disable
    public partial class _Imports : global::Microsoft.AspNetCore.Components.ComponentBase
    {
        #pragma warning disable 1998
        protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
        {
        }
        #pragma warning restore 1998
    }
}
#pragma warning restore 1591

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Blazorators

RSCG – Chorn.EmbeddedResourceAccessGenerator

RSCG – Chorn.EmbeddedResourceAccessGenerator
 
 

name Chorn.EmbeddedResourceAccessGenerator
nuget https://www.nuget.org/packages/Chorn.EmbeddedResourceAccessGenerator/
link https://github.com/ChristophHornung/EmbeddedResourceGenerator
author Christoph Hornung

Embedded Resources to C# Code

 

This is how you can use Chorn.EmbeddedResourceAccessGenerator .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	<ItemGroup>
	  <EmbeddedResource  Include="sql/*.sql" />
	</ItemGroup>
	<ItemGroup>
	  <PackageReference Include="Chorn.EmbeddedResourceAccessGenerator" Version="1.1.5" OutputItemType="Analyzer"  >
	    <PrivateAssets>all</PrivateAssets>
	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
	  </PackageReference>
	</ItemGroup>
	
	
</Project>


The code that you will use is


using EmbedDemo;
using StreamReader sr = EmbeddedResource.sql_createDB_sql.GetReader();
var data=sr.ReadToEnd();
Console.WriteLine(data);



create database Andrei;
GO;
use Andrei;
GO;


 

The code that is generated is

#nullable enable
namespace EmbedDemo;
using System;
using System.Collections;
using System.IO;
using System.Reflection;

/// <summary>
/// Auto-generated class to access all embedded resources in an assembly.
/// </summary>
public static partial class EmbeddedResources
{
	/// <summary>
	/// Gets the embedded resource 'sql.createDB.sql' as a stream.
	/// </summary>
	/// <returns>The stream to access the embedded resource.</returns>
	public static Stream sql_createDB_sql_Stream
	{
		get {
			Assembly assembly = typeof(EmbeddedResources).Assembly;
			string resource = "EmbedDemo.sql.createDB.sql";
			return assembly.GetManifestResourceStream(resource)!;
		}
	}

	/// <summary>
	/// Gets the embedded resource 'sql.createDB.sql' as a stream-reader.
	/// </summary>
	/// <returns>The stream-reader to access the embedded resource.</returns>
	public static StreamReader sql_createDB_sql_Reader
	{
		get 
		{
			Assembly assembly = typeof(EmbeddedResources).Assembly;
			string resource = "EmbedDemo.sql.createDB.sql";
			return new StreamReader(assembly.GetManifestResourceStream(resource)!);
		}
	}

	/// <summary>
	/// Gets the embedded resource's stream.
	/// </summary>
	/// <param name="resource">The embedded resource to retrieve the stream for.</param>
	/// <returns>The stream to access the embedded resource.</returns>
	public static Stream GetStream(this EmbeddedResource resource)
	{
		Assembly assembly = typeof(EmbeddedResources).Assembly;
		return assembly.GetManifestResourceStream(GetResourceName(resource))!;
	}

	/// <summary>
	/// Gets the embedded resource's stream-reader.
	/// </summary>
	/// <param name="resource">The embedded resource to retrieve the stream-reader for.</param>
	/// <returns>The stream-reader to access the embedded resource.</returns>
	public static StreamReader GetReader(this EmbeddedResource resource)
	{
		Assembly assembly = typeof(EmbeddedResources).Assembly;
		return new StreamReader(assembly.GetManifestResourceStream(GetResourceName(resource))!);
	}

	/// <summary>
	/// Gets the embedded resource's name in the format required by <c>GetManifestResourceStream</c>.
	/// </summary>
	/// <param name="resource">The embedded resource to retrieve the name for.</param>
	/// <returns>The name to access the embedded resource.</returns>
	public static string GetResourceName(this EmbeddedResource resource)
	{
		return resource switch 
		{
			EmbeddedResource.sql_createDB_sql => "EmbedDemo.sql.createDB.sql",
			_ => throw new InvalidOperationException(),
		};
	}

	/// <summary>
	/// Gets the embedded resource's stream.
	/// </summary>
	/// <param name="resource">The embedded resource to retrieve the stream for.</param>
	/// <returns>The stream to access the embedded resource.</returns>
	public static Stream GetStream(this EmbeddedResourcesql resource)
	{
		Assembly assembly = typeof(EmbeddedResources).Assembly;
		return assembly.GetManifestResourceStream(GetResourceName(resource))!;
	}

	/// <summary>
	/// Gets the embedded resource's stream-reader.
	/// </summary>
	/// <param name="resource">The embedded resource to retrieve the stream-reader for.</param>
	/// <returns>The stream-reader to access the embedded resource.</returns>
	public static StreamReader GetReader(this EmbeddedResourcesql resource)
	{
		Assembly assembly = typeof(EmbeddedResources).Assembly;
		return new StreamReader(assembly.GetManifestResourceStream(GetResourceName(resource))!);
	}

	/// <summary>
	/// Gets the embedded resource's name in the format required by <c>GetManifestResourceStream</c>.
	/// </summary>
	/// <param name="resource">The embedded resource to retrieve the name for.</param>
	/// <returns>The name to access the embedded resource.</returns>
	public static string GetResourceName(this EmbeddedResourcesql resource)
	{
		return resource switch 
		{
			EmbeddedResourcesql.createDB_sql => "EmbedDemo.sql.createDB.sql",
			_ => throw new InvalidOperationException(),
		};
	}
}

/// <summary>
/// Auto-generated enumeration for all embedded resources in the assembly.
/// </summary>
public enum EmbeddedResource
{
	/// <summary>
	/// Represents the embedded resource 'sql.createDB.sql'.
	/// </summary>
	sql_createDB_sql,
}

/// <summary>
/// Auto-generated enumeration for all embedded resources in 'sql'.
/// </summary>
public enum EmbeddedResourcesql
{
	/// <summary>
	/// Represents the embedded resource 'createDB.sql' in sql.
	/// </summary>
	createDB_sql,
}
#nullable restore

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Chorn.EmbeddedResourceAccessGenerator

RSCG – BuildInfo

RSCG – BuildInfo
 
 

name BuildInfo
nuget https://www.nuget.org/packages/BuildInfo/
link https://github.com/linkdotnet/BuildInformation
author Steven Giesel

Generating build information

 

This is how you can use BuildInfo .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>netcoreapp7.0</TargetFramework>
	</PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	<PropertyGroup>
		<UseRootNamespaceForBuildInformation>true</UseRootNamespaceForBuildInformation>
	</PropertyGroup>

	<ItemGroup>
		<CompilerVisibleProperty Include="UseRootNamespaceForBuildInformation" />
	</ItemGroup>

	<ItemGroup>
	  <PackageReference Include="LinkDotNet.BuildInformation" Version="1.0.0" />
		
	</ItemGroup>
	<PropertyGroup>
		<Version>2024.01.20</Version>
	</PropertyGroup>
</Project>


The code that you will use is


var strVersion = RSCG_Version.BuildInformation.AssemblyVersion;
System.Console.WriteLine(strVersion);


 

The code that is generated is

// <auto-generated>
// This file was generated by the LinkDotNet.BuildInformation package.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>

using System;
using System.Globalization;

namespace RSCG_Version;

internal static class BuildInformation
{
    /// <summary>
    /// Returns the build date (UTC).
    /// </summary>
    /// <remarks>Value is: 2024-01-21T07:37:28.4648410Z</remarks>
    public static readonly DateTime BuildAt = DateTime.ParseExact("2024-01-21T07:37:28.4648410Z", "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);

    /// <summary>
    /// Returns the platform.
    /// </summary>
    /// <remarks>Value is: AnyCpu</remarks>
    public const string Platform = "AnyCpu";

    /// <summary>
    /// Returns the warning level.
    /// </summary>
    /// <remarks>Value is: 7</remarks>
    public const int WarningLevel = 7;

    /// <summary>
    /// Returns the configuration.
    /// </summary>
    /// <remarks>Value is: Release</remarks>
    public const string Configuration = "Release";

    /// <summary>
    /// Returns the assembly version.
    /// </summary>
    /// <remarks>Value is: 2024.1.20.0</remarks>
    public const string AssemblyVersion = "2024.1.20.0";

    /// <summary>
    /// Returns the assembly file version.
    /// </summary>
    /// <remarks>Value is: 2024.1.20.0</remarks>
    public const string AssemblyFileVersion = "2024.1.20.0";

    /// <summary>
    /// Returns the assembly name.
    /// </summary>
    /// <remarks>Value is: RSCG_Version</remarks>
    public const string AssemblyName = "RSCG_Version";

    /// <summary>
    /// Returns the target framework moniker.
    /// </summary>
    /// <remarks>Value is: netcoreapp7.0</remarks>
    public const string TargetFrameworkMoniker = "netcoreapp7.0";

    /// <summary>
    /// Returns the nullability level.
    /// </summary>
    /// <remarks>Value is: Disable</remarks>
    public const string Nullability = "Disable";

    /// <summary>
    /// Returns whether the build is deterministic.
    /// </summary>
    /// <remarks>Value is: true</remarks>
    public const bool Deterministic = true;
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/BuildInfo

RSCG – MakeInterface.Generator

RSCG – MakeInterface.Generator
 
 

name MakeInterface.Generator
nuget https://www.nuget.org/packages/MakeInterface.Generator/
link https://github.com/Frederik91/MakeInterface
author Frederik

Generating interface from class definition

 

This is how you can use MakeInterface.Generator .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MakeInterface.Contracts" Version="0.4.0" />
    <PackageReference Include="MakeInterface.Generator" Version="0.4.0" OutputItemType="Analyzer" >
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


// See https://aka.ms/new-console-template for more information
using Class2Interface;

Console.WriteLine("Hello, World!");
IPerson person=new Person();
person.FirstName="Andrei";
person.LastName="Ignat";
Console.WriteLine(person.FullName());


using MakeInterface.Contracts.Attributes;

namespace Class2Interface;
[GenerateInterface]
internal class Person:IPerson
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Name
    {
        get
        {
            return $"{FirstName} {LastName}";
        }
    }
    public string FullName()
    {
        return $"{FirstName} {LastName}";
    }
}


 

The code that is generated is

using MakeInterface.Contracts.Attributes;

// <auto-generated/>
#pragma warning disable
#nullable enable
namespace Class2Interface;
public partial interface IPerson
{
    int ID { get; set; }

    string FirstName { get; set; }

    string LastName { get; set; }

    string Name { get; }

    string FullName();
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/MakeInterface.Generator

RSCG – Funcky.DiscriminatedUnion

RSCG – Funcky.DiscriminatedUnion
 
 

name Funcky.DiscriminatedUnion
nuget https://www.nuget.org/packages/Funcky.DiscriminatedUnion/
link https://github.com/polyadic/funcky-discriminated-union
author Polyadic

Generating discriminated unions for C# 9.0 and above.

 

This is how you can use Funcky.DiscriminatedUnion .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Funcky.DiscriminatedUnion" Version="1.1.0"  />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using Union;

Console.WriteLine("Save or not");
var data = SaveToDatabase.Save(0);

Console.WriteLine(data.Match(ok => true, error => false));
data = SaveToDatabase.Save(1);
Console.WriteLine(data.Match(ok => true, error => false));



namespace Union;

[Funcky.DiscriminatedUnion]
public abstract partial record ResultSave
{
    public partial record Success(int Value): ResultSave;
    public partial record ValidationError(string Message):ResultSave;

    //public sealed partial record Ok(T Value) : ResultSave<T>;

    //public sealed partial record Error(Exception Exception) : ResultSave<T>;
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Union;
internal class SaveToDatabase
{
    public static ResultSave Save(int i)
    {
        if (i == 0)
        {
            return new ResultSave.ValidationError(" cannot save 0");
        }
        return new ResultSave.Success(i);
    }
}


 

The code that is generated is

// <auto-generated/>
#nullable enable

namespace Funcky
{
    [global::System.Diagnostics.Conditional("Funcky_DiscriminatedUnion")]
    [global::System.AttributeUsage(global::System.AttributeTargets.Class)]
    internal sealed class DiscriminatedUnionAttribute : global::System.Attribute
    {
        /// <summary>Allow only consumers in the same assembly to use the exhaustive <c>Match</c> and <c>Switch</c> methods.</summary>
        public bool NonExhaustive { get; set; }

        /// <summary>Generates exhaustive <c>Match</c> and <c>Switch</c> methods for the entire type hierarchy.</summary>
        public bool Flatten { get; set; }

        /// <summary>Customized the generic type name used for the result in the generated <c>Match</c> methods. Defaults to <c>TResult</c>.</summary>
        public string? MatchResultTypeName { get; set; }
    }
}

// <auto-generated/>
#nullable enable

namespace Union
{
    partial record ResultSave
    {
        [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")]
        public abstract TResult Match<TResult>(global::System.Func<Success, TResult> success, global::System.Func<ValidationError, TResult> validationError);
        
        [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")]
        public abstract void Switch(global::System.Action<Success> success, global::System.Action<ValidationError> validationError);
        
        partial record Success
        {
            [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")]
            public override TResult Match<TResult>(global::System.Func<Success, TResult> success, global::System.Func<ValidationError, TResult> validationError) => success(this);
            
            [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")]
            public override void Switch(global::System.Action<Success> success, global::System.Action<ValidationError> validationError) => success(this);
        }
        
        partial record ValidationError
        {
            [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")]
            public override TResult Match<TResult>(global::System.Func<Success, TResult> success, global::System.Func<ValidationError, TResult> validationError) => validationError(this);
            
            [global::System.CodeDom.Compiler.GeneratedCode("Funcky.DiscriminatedUnion.SourceGeneration", "1.1.0.0")]
            public override void Switch(global::System.Action<Success> success, global::System.Action<ValidationError> validationError) => validationError(this);
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Funcky.DiscriminatedUnion

RSCG – DomainPrimitives

RSCG – DomainPrimitives
 
 

name DomainPrimitives
nuget https://www.nuget.org/packages/AltaSoft.DomainPrimitives.Generator
https://www.nuget.org/packages/AltaSoft.DomainPrimitives.Abstractions
link https://github.com/altasoft/DomainPrimitives
author Alta Software – Teimuraz Nikolaishvili

One of the most complete and mature libraries for DomainPrimitives in .NET

 

This is how you can use DomainPrimitives .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="AltaSoft.DomainPrimitives.Abstractions" Version="1.0.3" />
		<PackageReference Include="AltaSoft.DomainPrimitives.Generator" Version="1.0.3" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="all" ExcludeAssets="runtime" />
	</ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>

	<PropertyGroup>
		<!--<DomainPrimitiveGenerator_GenerateJsonConverters>false</DomainPrimitiveGenerator_GenerateJsonConverters>-->
		<!--<DomainPrimitiveGenerator_GenerateTypeConverters>false</DomainPrimitiveGenerator_GenerateTypeConverters>-->
		<DomainPrimitiveGenerator_GenerateSwaggerConverters>false</DomainPrimitiveGenerator_GenerateSwaggerConverters>
	</PropertyGroup>
	<ItemGroup>
		<!--<CompilerVisibleProperty Include="DomainPrimitiveGenerator_GenerateTypeConverters" />-->
		<!--<CompilerVisibleProperty Include="DomainPrimitiveGenerator_GenerateJsonConverters" />-->
		<CompilerVisibleProperty Include="DomainPrimitiveGenerator_GenerateSwaggerConverters" />
	</ItemGroup>

</Project>


The code that you will use is


// See https://aka.ms/new-console-template for more information
using DomainPrimitives;

var year = new YearDate(1970);
var month = new MonthDate(4);
var day = new DayDate(16);
year += 1;
var p=new Person(year,month,day);

Console.WriteLine(p.DOB);


using AltaSoft.DomainPrimitives.Abstractions;

namespace DomainPrimitives;

public readonly partial record struct YearDate : IDomainValue<int>
{
    public static void Validate(int value)
    {
        if (value <= 0)
            throw new InvalidDomainValueException("year must be positive");
    }
    public static int Default => 1;
}
public readonly partial record struct MonthDate : IDomainValue<int>
{
    public static void Validate(int value)
    {
        if (value <= 0)
            throw new InvalidDomainValueException("year must be positive");
    }
    public static int Default => 1;
}

public readonly partial record struct DayDate : IDomainValue<int>
{
    public static void Validate(int value)
    {
        if (value <= 0)
            throw new InvalidDomainValueException("year must be positive");
    }
    public static int Default => 1;
}



namespace DomainPrimitives;
internal class Person
{
    public Person(YearDate year,MonthDate month,DayDate day)
    {
        DOB = new DateOnly(year,month,day);
    }
    public DateOnly DOB { get; private set; }

    
}


 

The code that is generated is

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using System;
using System.Numerics;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
using DomainPrimitives.Converters;
using System.ComponentModel;

namespace DomainPrimitives;

[JsonConverter(typeof(DayDateJsonConverter))]
[TypeConverter(typeof(DayDateTypeConverter))]
[DebuggerDisplay("{_valueOrDefault}")]
public readonly partial record struct DayDate :
		IAdditionOperators<DayDate, DayDate, DayDate>,
		ISubtractionOperators<DayDate, DayDate, DayDate>,
		IMultiplyOperators<DayDate, DayDate, DayDate>,
		IDivisionOperators<DayDate, DayDate, DayDate>,
		IModulusOperators<DayDate, DayDate, DayDate>,
		IComparisonOperators<DayDate, DayDate, bool>,
		IComparable,
		IComparable<DayDate>,
		IParsable<DayDate>,
		IConvertible
{
	private int _valueOrDefault => _isInitialized ? _value : Default;
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private readonly int _value;
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private readonly bool _isInitialized;
	
	/// <summary>
	/// Initializes a new instance of the <see cref="DayDate"/> class by validating the specified <see cref="int"/> value using <see cref="Validate"/> static method.
	/// </summary>
	/// <param name="value">The value to be validated..</param>
	public DayDate(int value)
	{
			Validate(value);
			_value = value;
			_isInitialized = true;
	}
	
	[Obsolete("Domain primitive cannot be created using empty Ctor", true)]
	public DayDate() : this(Default)
	{
	}
	
	/// <summary>
	/// <summary>Implicit conversion from <see cref = "int"/> to <see cref = "DayDate"/></summary>
	/// </summary>
	public static implicit operator DayDate(int value) => new(value);

	/// <summary>
	/// <summary>Implicit conversion from <see cref = "int?"/> to <see cref = "DayDate?"/></summary>
	/// </summary>
	[return: NotNullIfNotNull(nameof(value))]
	public static implicit operator DayDate?(int? value) => value is null ? null : new(value.Value);

	/// <summary>
	/// <summary>Implicit conversion from <see cref = "DayDate"/> to <see cref = "int"/></summary>
	/// </summary>
	public static implicit operator int(DayDate value) => (int)value._valueOrDefault;

	/// <inheritdoc/>
	public static DayDate operator +(DayDate left, DayDate right) => new(left._valueOrDefault + right._valueOrDefault);

	/// <inheritdoc/>
	public static DayDate operator -(DayDate left, DayDate right) => new(left._valueOrDefault - right._valueOrDefault);

	/// <inheritdoc/>
	public static DayDate operator *(DayDate left, DayDate right) => new(left._valueOrDefault * right._valueOrDefault);

	/// <inheritdoc/>
	public static DayDate operator /(DayDate left, DayDate right) => new(left._valueOrDefault / right._valueOrDefault);

	/// <inheritdoc/>
	public static DayDate operator %(DayDate left, DayDate right) => new(left._valueOrDefault % right._valueOrDefault);

	/// <inheritdoc/>
	public int CompareTo(object? value)
	{
		if (value is null)
			return 1;

		if (value is DayDate c)
			return CompareTo(c);

		throw new ArgumentException("Object is not a DayDate", nameof(value));
	}

	/// <inheritdoc/>
	public int CompareTo(DayDate other) => _valueOrDefault.CompareTo(other._valueOrDefault);

	/// <inheritdoc/>
	public static bool operator <(DayDate left, DayDate right) => left._valueOrDefault < right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator <=(DayDate left, DayDate right) => left._valueOrDefault <= right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator >(DayDate left, DayDate right) => left._valueOrDefault > right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator >=(DayDate left, DayDate right) => left._valueOrDefault >= right._valueOrDefault;


	/// <inheritdoc/>
	public static DayDate Parse(string s, IFormatProvider? provider) => int.Parse(s, provider);

	/// <inheritdoc/>
	public static bool TryParse(string? s, IFormatProvider? provider, out DayDate result)
	{
		if (int.TryParse(s, provider, out var value))
		{
			result = new DayDate(value);
			return true;
		}
		result = default;
		return false;
	}


	/// <inheritdoc/>
	public override string ToString() => _valueOrDefault.ToString();

	/// <inheritdoc/>
	TypeCode IConvertible.GetTypeCode() => ((IConvertible)_valueOrDefault).GetTypeCode();

	/// <inheritdoc/>
	bool IConvertible.ToBoolean(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToBoolean(provider);

	/// <inheritdoc/>
	byte IConvertible.ToByte(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToByte(provider);

	/// <inheritdoc/>
	char IConvertible.ToChar(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToChar(provider);

	/// <inheritdoc/>
	DateTime IConvertible.ToDateTime(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDateTime(provider);

	/// <inheritdoc/>
	decimal IConvertible.ToDecimal(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDecimal(provider);

	/// <inheritdoc/>
	double IConvertible.ToDouble(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDouble(provider);

	/// <inheritdoc/>
	short IConvertible.ToInt16(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt16(provider);

	/// <inheritdoc/>
	int IConvertible.ToInt32(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt32(provider);

	/// <inheritdoc/>
	long IConvertible.ToInt64(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt64(provider);

	/// <inheritdoc/>
	sbyte IConvertible.ToSByte(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToSByte(provider);

	/// <inheritdoc/>
	float IConvertible.ToSingle(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToSingle(provider);

	/// <inheritdoc/>
	string IConvertible.ToString(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToString(provider);

	/// <inheritdoc/>
	object IConvertible.ToType(Type conversionType, IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToType(conversionType, provider);

	/// <inheritdoc/>
	ushort IConvertible.ToUInt16(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt16(provider);

	/// <inheritdoc/>
	uint IConvertible.ToUInt32(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt32(provider);

	/// <inheritdoc/>
	ulong IConvertible.ToUInt64(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt64(provider);
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using DomainPrimitives;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Globalization;
using System.Text.Json.Serialization.Metadata;
using AltaSoft.DomainPrimitives.Abstractions;

namespace DomainPrimitives.Converters;

/// <summary>
/// JsonConverter for <see cref = "DayDate"/>
/// </summary>
public sealed class DayDateJsonConverter : JsonConverter<DayDate>
{
	/// <inheritdoc/>
	public override DayDate Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		try
		{
			return JsonInternalConverters.Int32Converter.Read(ref reader, typeToConvert, options);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new JsonException(ex.Message);
		}
	}

	/// <inheritdoc/>
	public override void Write(Utf8JsonWriter writer, DayDate value, JsonSerializerOptions options)
	{
		JsonInternalConverters.Int32Converter.Write(writer, (int)value, options);
	}

	/// <inheritdoc/>
	public override DayDate ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		try
		{
			return JsonInternalConverters.Int32Converter.ReadAsPropertyName(ref reader, typeToConvert, options);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new JsonException(ex.Message);
		}
	}

	/// <inheritdoc/>
	public override void WriteAsPropertyName(Utf8JsonWriter writer, DayDate value, JsonSerializerOptions options)
	{
		JsonInternalConverters.Int32Converter.WriteAsPropertyName(writer, (int)value, options);
	}
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using DomainPrimitives;
using System;
using System.ComponentModel;
using System.Globalization;
using AltaSoft.DomainPrimitives.Abstractions;

namespace DomainPrimitives.Converters;

/// <summary>
/// TypeConverter for <see cref = "DayDate"/>
/// </summary>
public sealed class DayDateTypeConverter : Int32Converter
{
	/// <inheritdoc/>
	public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
	{
		var result = base.ConvertFrom(context, culture, value);
		if (result is null)
			return null;
		try
		{
			return new DayDate((int)result);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new FormatException("Cannot parse DayDate", ex);
		}
	}
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using System;
using System.Numerics;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
using DomainPrimitives.Converters;
using System.ComponentModel;

namespace DomainPrimitives;

[JsonConverter(typeof(MonthDateJsonConverter))]
[TypeConverter(typeof(MonthDateTypeConverter))]
[DebuggerDisplay("{_valueOrDefault}")]
public readonly partial record struct MonthDate :
		IAdditionOperators<MonthDate, MonthDate, MonthDate>,
		ISubtractionOperators<MonthDate, MonthDate, MonthDate>,
		IMultiplyOperators<MonthDate, MonthDate, MonthDate>,
		IDivisionOperators<MonthDate, MonthDate, MonthDate>,
		IModulusOperators<MonthDate, MonthDate, MonthDate>,
		IComparisonOperators<MonthDate, MonthDate, bool>,
		IComparable,
		IComparable<MonthDate>,
		IParsable<MonthDate>,
		IConvertible
{
	private int _valueOrDefault => _isInitialized ? _value : Default;
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private readonly int _value;
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private readonly bool _isInitialized;
	
	/// <summary>
	/// Initializes a new instance of the <see cref="MonthDate"/> class by validating the specified <see cref="int"/> value using <see cref="Validate"/> static method.
	/// </summary>
	/// <param name="value">The value to be validated..</param>
	public MonthDate(int value)
	{
			Validate(value);
			_value = value;
			_isInitialized = true;
	}
	
	[Obsolete("Domain primitive cannot be created using empty Ctor", true)]
	public MonthDate() : this(Default)
	{
	}
	
	/// <summary>
	/// <summary>Implicit conversion from <see cref = "int"/> to <see cref = "MonthDate"/></summary>
	/// </summary>
	public static implicit operator MonthDate(int value) => new(value);

	/// <summary>
	/// <summary>Implicit conversion from <see cref = "int?"/> to <see cref = "MonthDate?"/></summary>
	/// </summary>
	[return: NotNullIfNotNull(nameof(value))]
	public static implicit operator MonthDate?(int? value) => value is null ? null : new(value.Value);

	/// <summary>
	/// <summary>Implicit conversion from <see cref = "MonthDate"/> to <see cref = "int"/></summary>
	/// </summary>
	public static implicit operator int(MonthDate value) => (int)value._valueOrDefault;

	/// <inheritdoc/>
	public static MonthDate operator +(MonthDate left, MonthDate right) => new(left._valueOrDefault + right._valueOrDefault);

	/// <inheritdoc/>
	public static MonthDate operator -(MonthDate left, MonthDate right) => new(left._valueOrDefault - right._valueOrDefault);

	/// <inheritdoc/>
	public static MonthDate operator *(MonthDate left, MonthDate right) => new(left._valueOrDefault * right._valueOrDefault);

	/// <inheritdoc/>
	public static MonthDate operator /(MonthDate left, MonthDate right) => new(left._valueOrDefault / right._valueOrDefault);

	/// <inheritdoc/>
	public static MonthDate operator %(MonthDate left, MonthDate right) => new(left._valueOrDefault % right._valueOrDefault);

	/// <inheritdoc/>
	public int CompareTo(object? value)
	{
		if (value is null)
			return 1;

		if (value is MonthDate c)
			return CompareTo(c);

		throw new ArgumentException("Object is not a MonthDate", nameof(value));
	}

	/// <inheritdoc/>
	public int CompareTo(MonthDate other) => _valueOrDefault.CompareTo(other._valueOrDefault);

	/// <inheritdoc/>
	public static bool operator <(MonthDate left, MonthDate right) => left._valueOrDefault < right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator <=(MonthDate left, MonthDate right) => left._valueOrDefault <= right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator >(MonthDate left, MonthDate right) => left._valueOrDefault > right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator >=(MonthDate left, MonthDate right) => left._valueOrDefault >= right._valueOrDefault;


	/// <inheritdoc/>
	public static MonthDate Parse(string s, IFormatProvider? provider) => int.Parse(s, provider);

	/// <inheritdoc/>
	public static bool TryParse(string? s, IFormatProvider? provider, out MonthDate result)
	{
		if (int.TryParse(s, provider, out var value))
		{
			result = new MonthDate(value);
			return true;
		}
		result = default;
		return false;
	}


	/// <inheritdoc/>
	public override string ToString() => _valueOrDefault.ToString();

	/// <inheritdoc/>
	TypeCode IConvertible.GetTypeCode() => ((IConvertible)_valueOrDefault).GetTypeCode();

	/// <inheritdoc/>
	bool IConvertible.ToBoolean(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToBoolean(provider);

	/// <inheritdoc/>
	byte IConvertible.ToByte(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToByte(provider);

	/// <inheritdoc/>
	char IConvertible.ToChar(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToChar(provider);

	/// <inheritdoc/>
	DateTime IConvertible.ToDateTime(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDateTime(provider);

	/// <inheritdoc/>
	decimal IConvertible.ToDecimal(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDecimal(provider);

	/// <inheritdoc/>
	double IConvertible.ToDouble(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDouble(provider);

	/// <inheritdoc/>
	short IConvertible.ToInt16(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt16(provider);

	/// <inheritdoc/>
	int IConvertible.ToInt32(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt32(provider);

	/// <inheritdoc/>
	long IConvertible.ToInt64(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt64(provider);

	/// <inheritdoc/>
	sbyte IConvertible.ToSByte(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToSByte(provider);

	/// <inheritdoc/>
	float IConvertible.ToSingle(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToSingle(provider);

	/// <inheritdoc/>
	string IConvertible.ToString(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToString(provider);

	/// <inheritdoc/>
	object IConvertible.ToType(Type conversionType, IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToType(conversionType, provider);

	/// <inheritdoc/>
	ushort IConvertible.ToUInt16(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt16(provider);

	/// <inheritdoc/>
	uint IConvertible.ToUInt32(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt32(provider);

	/// <inheritdoc/>
	ulong IConvertible.ToUInt64(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt64(provider);
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using DomainPrimitives;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Globalization;
using System.Text.Json.Serialization.Metadata;
using AltaSoft.DomainPrimitives.Abstractions;

namespace DomainPrimitives.Converters;

/// <summary>
/// JsonConverter for <see cref = "MonthDate"/>
/// </summary>
public sealed class MonthDateJsonConverter : JsonConverter<MonthDate>
{
	/// <inheritdoc/>
	public override MonthDate Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		try
		{
			return JsonInternalConverters.Int32Converter.Read(ref reader, typeToConvert, options);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new JsonException(ex.Message);
		}
	}

	/// <inheritdoc/>
	public override void Write(Utf8JsonWriter writer, MonthDate value, JsonSerializerOptions options)
	{
		JsonInternalConverters.Int32Converter.Write(writer, (int)value, options);
	}

	/// <inheritdoc/>
	public override MonthDate ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		try
		{
			return JsonInternalConverters.Int32Converter.ReadAsPropertyName(ref reader, typeToConvert, options);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new JsonException(ex.Message);
		}
	}

	/// <inheritdoc/>
	public override void WriteAsPropertyName(Utf8JsonWriter writer, MonthDate value, JsonSerializerOptions options)
	{
		JsonInternalConverters.Int32Converter.WriteAsPropertyName(writer, (int)value, options);
	}
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using DomainPrimitives;
using System;
using System.ComponentModel;
using System.Globalization;
using AltaSoft.DomainPrimitives.Abstractions;

namespace DomainPrimitives.Converters;

/// <summary>
/// TypeConverter for <see cref = "MonthDate"/>
/// </summary>
public sealed class MonthDateTypeConverter : Int32Converter
{
	/// <inheritdoc/>
	public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
	{
		var result = base.ConvertFrom(context, culture, value);
		if (result is null)
			return null;
		try
		{
			return new MonthDate((int)result);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new FormatException("Cannot parse MonthDate", ex);
		}
	}
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using System;
using System.Numerics;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
using DomainPrimitives.Converters;
using System.ComponentModel;

namespace DomainPrimitives;

[JsonConverter(typeof(YearDateJsonConverter))]
[TypeConverter(typeof(YearDateTypeConverter))]
[DebuggerDisplay("{_valueOrDefault}")]
public readonly partial record struct YearDate :
		IAdditionOperators<YearDate, YearDate, YearDate>,
		ISubtractionOperators<YearDate, YearDate, YearDate>,
		IMultiplyOperators<YearDate, YearDate, YearDate>,
		IDivisionOperators<YearDate, YearDate, YearDate>,
		IModulusOperators<YearDate, YearDate, YearDate>,
		IComparisonOperators<YearDate, YearDate, bool>,
		IComparable,
		IComparable<YearDate>,
		IParsable<YearDate>,
		IConvertible
{
	private int _valueOrDefault => _isInitialized ? _value : Default;
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private readonly int _value;
	[DebuggerBrowsable(DebuggerBrowsableState.Never)]
	private readonly bool _isInitialized;
	
	/// <summary>
	/// Initializes a new instance of the <see cref="YearDate"/> class by validating the specified <see cref="int"/> value using <see cref="Validate"/> static method.
	/// </summary>
	/// <param name="value">The value to be validated..</param>
	public YearDate(int value)
	{
			Validate(value);
			_value = value;
			_isInitialized = true;
	}
	
	[Obsolete("Domain primitive cannot be created using empty Ctor", true)]
	public YearDate() : this(Default)
	{
	}
	
	/// <summary>
	/// <summary>Implicit conversion from <see cref = "int"/> to <see cref = "YearDate"/></summary>
	/// </summary>
	public static implicit operator YearDate(int value) => new(value);

	/// <summary>
	/// <summary>Implicit conversion from <see cref = "int?"/> to <see cref = "YearDate?"/></summary>
	/// </summary>
	[return: NotNullIfNotNull(nameof(value))]
	public static implicit operator YearDate?(int? value) => value is null ? null : new(value.Value);

	/// <summary>
	/// <summary>Implicit conversion from <see cref = "YearDate"/> to <see cref = "int"/></summary>
	/// </summary>
	public static implicit operator int(YearDate value) => (int)value._valueOrDefault;

	/// <inheritdoc/>
	public static YearDate operator +(YearDate left, YearDate right) => new(left._valueOrDefault + right._valueOrDefault);

	/// <inheritdoc/>
	public static YearDate operator -(YearDate left, YearDate right) => new(left._valueOrDefault - right._valueOrDefault);

	/// <inheritdoc/>
	public static YearDate operator *(YearDate left, YearDate right) => new(left._valueOrDefault * right._valueOrDefault);

	/// <inheritdoc/>
	public static YearDate operator /(YearDate left, YearDate right) => new(left._valueOrDefault / right._valueOrDefault);

	/// <inheritdoc/>
	public static YearDate operator %(YearDate left, YearDate right) => new(left._valueOrDefault % right._valueOrDefault);

	/// <inheritdoc/>
	public int CompareTo(object? value)
	{
		if (value is null)
			return 1;

		if (value is YearDate c)
			return CompareTo(c);

		throw new ArgumentException("Object is not a YearDate", nameof(value));
	}

	/// <inheritdoc/>
	public int CompareTo(YearDate other) => _valueOrDefault.CompareTo(other._valueOrDefault);

	/// <inheritdoc/>
	public static bool operator <(YearDate left, YearDate right) => left._valueOrDefault < right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator <=(YearDate left, YearDate right) => left._valueOrDefault <= right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator >(YearDate left, YearDate right) => left._valueOrDefault > right._valueOrDefault;

	/// <inheritdoc/>
	public static bool operator >=(YearDate left, YearDate right) => left._valueOrDefault >= right._valueOrDefault;


	/// <inheritdoc/>
	public static YearDate Parse(string s, IFormatProvider? provider) => int.Parse(s, provider);

	/// <inheritdoc/>
	public static bool TryParse(string? s, IFormatProvider? provider, out YearDate result)
	{
		if (int.TryParse(s, provider, out var value))
		{
			result = new YearDate(value);
			return true;
		}
		result = default;
		return false;
	}


	/// <inheritdoc/>
	public override string ToString() => _valueOrDefault.ToString();

	/// <inheritdoc/>
	TypeCode IConvertible.GetTypeCode() => ((IConvertible)_valueOrDefault).GetTypeCode();

	/// <inheritdoc/>
	bool IConvertible.ToBoolean(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToBoolean(provider);

	/// <inheritdoc/>
	byte IConvertible.ToByte(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToByte(provider);

	/// <inheritdoc/>
	char IConvertible.ToChar(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToChar(provider);

	/// <inheritdoc/>
	DateTime IConvertible.ToDateTime(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDateTime(provider);

	/// <inheritdoc/>
	decimal IConvertible.ToDecimal(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDecimal(provider);

	/// <inheritdoc/>
	double IConvertible.ToDouble(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToDouble(provider);

	/// <inheritdoc/>
	short IConvertible.ToInt16(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt16(provider);

	/// <inheritdoc/>
	int IConvertible.ToInt32(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt32(provider);

	/// <inheritdoc/>
	long IConvertible.ToInt64(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToInt64(provider);

	/// <inheritdoc/>
	sbyte IConvertible.ToSByte(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToSByte(provider);

	/// <inheritdoc/>
	float IConvertible.ToSingle(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToSingle(provider);

	/// <inheritdoc/>
	string IConvertible.ToString(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToString(provider);

	/// <inheritdoc/>
	object IConvertible.ToType(Type conversionType, IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToType(conversionType, provider);

	/// <inheritdoc/>
	ushort IConvertible.ToUInt16(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt16(provider);

	/// <inheritdoc/>
	uint IConvertible.ToUInt32(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt32(provider);

	/// <inheritdoc/>
	ulong IConvertible.ToUInt64(IFormatProvider? provider) => ((IConvertible)_valueOrDefault).ToUInt64(provider);
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using DomainPrimitives;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Globalization;
using System.Text.Json.Serialization.Metadata;
using AltaSoft.DomainPrimitives.Abstractions;

namespace DomainPrimitives.Converters;

/// <summary>
/// JsonConverter for <see cref = "YearDate"/>
/// </summary>
public sealed class YearDateJsonConverter : JsonConverter<YearDate>
{
	/// <inheritdoc/>
	public override YearDate Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		try
		{
			return JsonInternalConverters.Int32Converter.Read(ref reader, typeToConvert, options);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new JsonException(ex.Message);
		}
	}

	/// <inheritdoc/>
	public override void Write(Utf8JsonWriter writer, YearDate value, JsonSerializerOptions options)
	{
		JsonInternalConverters.Int32Converter.Write(writer, (int)value, options);
	}

	/// <inheritdoc/>
	public override YearDate ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		try
		{
			return JsonInternalConverters.Int32Converter.ReadAsPropertyName(ref reader, typeToConvert, options);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new JsonException(ex.Message);
		}
	}

	/// <inheritdoc/>
	public override void WriteAsPropertyName(Utf8JsonWriter writer, YearDate value, JsonSerializerOptions options)
	{
		JsonInternalConverters.Int32Converter.WriteAsPropertyName(writer, (int)value, options);
	}
}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a AltaSoft.DomainPrimitives.Generator v1.0.0
//     Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

using DomainPrimitives;
using System;
using System.ComponentModel;
using System.Globalization;
using AltaSoft.DomainPrimitives.Abstractions;

namespace DomainPrimitives.Converters;

/// <summary>
/// TypeConverter for <see cref = "YearDate"/>
/// </summary>
public sealed class YearDateTypeConverter : Int32Converter
{
	/// <inheritdoc/>
	public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
	{
		var result = base.ConvertFrom(context, culture, value);
		if (result is null)
			return null;
		try
		{
			return new YearDate((int)result);
		}
		catch (InvalidDomainValueException ex)
		{
			throw new FormatException("Cannot parse YearDate", ex);
		}
	}
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/DomainPrimitives

RSCG – HsuSgSync

RSCG – HsuSgSync
 
 

name HsuSgSync
nuget https://www.nuget.org/packages/Hsu.Sg.Sync/
link https://github.com/hsu-net/source-generators
author Net Hsu

Generate code for async to sync methods

 

This is how you can use HsuSgSync .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Hsu.Sg.Sync" Version="2023.412.21" OutputItemType="Analyzer" >
    </PackageReference>
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using HsuSgSync;

var p=new Person();
var result=await p.RunAsync();
Console.WriteLine(result);
result=p.Run();



using System.ComponentModel;
using Hsu.Sg.Sync;
namespace HsuSgSync;
[Sync]
internal partial class Person
{   
    public async Task<bool> RunAsync()
    {
        await Task.Delay(1000);
        return true;
    }
}


 

The code that is generated is

// <auto-generated/>

using System;

namespace Hsu.Sg.Sync
{
    /// <summary>
    /// The flag to generate async method to sync method.
    /// </summary>
    [AttributeUsage(
        System.AttributeTargets.Interface |
        System.AttributeTargets.Struct |
        System.AttributeTargets.Class,
        AllowMultiple = false,
        Inherited = false)]
    internal sealed class SyncAttribute : Attribute
    {
        /// <summary>
        ///     Only <c>interface</c> or <c>abstract</c> async methods are generated.
        /// </summary>
        public bool Definable { get; set; }
        
        /// <summary>
        /// The public async methods are generated.
        /// </summary>
        public bool Public { get; set; } = true;

        /// <summary>
        /// The internal async methods are generated.
        /// </summary>
        public bool Internal { get; set; } = true;

        /// <summary>
        /// The private async methods are generated.
        /// </summary>
        public bool Private { get; set; } = true;

        /// <summary>
        /// Only [SyncGen] async methods are generated.
        /// </summary>
        public bool Only { get; set; } = false;

        /// <summary>
        /// The suffix of sync method name when not end with Async.
        /// </summary>
        /// <remarks>default is `Sync`</remarks>
        public string Suffix { get; set; } = string.Empty;

        /// <summary>
        /// Whether generate attributes.
        /// </summary>
        public bool Attribute { get; set; } = false;

        /// <summary>
        /// To generate with attributes
        /// </summary>
        public string[] AttributeIncludes { get; set; } = null;

        /// <summary>
        /// To generate without attributes
        /// </summary>
        public string[] AttributeExcludes { get; set; } = null;

        public SyncAttribute()
        {
            Public = true;
            Internal = true;
            Private = true;
            Only = false;
            Suffix = string.Empty;
        }
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    internal sealed class SyncGenAttribute : Attribute
    {
        /// <summary>
        /// Ignore to generate sync methods. 
        /// </summary>
        public bool Ignore { get; set; } = false;
        
        /// <summary>
        /// The specific name of sync method.
        /// </summary>
        public string Identifier { get; set; } = string.Empty;

        /// <summary>
        /// The suffix of sync method name when not end with Async.
        /// </summary>
        /// <remarks>default is `Sync`</remarks>
        public string Suffix { get; set; } = string.Empty;
    }
}
// <auto-generated/>

using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System;

namespace Hsu.Sg.Sync
{
    internal static partial class SyncHelper
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Run(Task task)
        {
            Nito.AsyncEx.AsyncContext.Run(async () => await task);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Run<T>(Task<T> task)
        {
            return Nito.AsyncEx.AsyncContext.Run(async () => await task);
        }
        
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Run(Func<Task> task)
        {
            Nito.AsyncEx.AsyncContext.Run(async () => await task());
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Run<T>(Func<Task<T>> task)
        {
            return Nito.AsyncEx.AsyncContext.Run(async () => await task());
        }
    }
}
// <auto-generated/>

using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System;

namespace Hsu.Sg.Sync
{
    internal static partial class SyncHelper
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Run(ValueTask task)
        {
            Nito.AsyncEx.AsyncContext.Run(async () => await task);
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Run<T>(ValueTask<T> task)
        {
            return Nito.AsyncEx.AsyncContext.Run(async () => await task);
        }
        
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static void Run(Func<ValueTask> task)
        {
            Nito.AsyncEx.AsyncContext.Run(async () => await task());
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static T Run<T>(Func<ValueTask<T>> task)
        {
            return Nito.AsyncEx.AsyncContext.Run(async () => await task());
        }
    }
}
// <auto-generated/>
// Generated 1 sync methods by SyncGenerator
// ValueTaskSupported : True
// DefaultImplementationsOfInterfacesSupported : True
// Metadata { Only = False, Definable = False, Public = True, Internal = True, Private = True, Attribute = False  }

using System.ComponentModel;

namespace HsuSgSync;

internal partial class Person
{
    /// <inheritdoc cref="RunAsync()" />
    /// <remarks></remarks>
    public bool Run() 
    	=> Hsu.Sg.Sync.SyncHelper.Run(() => RunAsync());
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/HsuSgSync

RSCG – CopyCat

RSCG – CopyCat
 
 

name CopyCat
nuget https://www.nuget.org/packages/Copycat/
link https://github.com/Otaman/Copycat/
author Serhii Buta

Implementation of the Decorator pattern in C# – only for not implemented methods

 

This is how you can use CopyCat .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Copycat" Version="0.2.0-beta.1" OutputItemType="Analyzer"   />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using CCDemo;

ICoffee c =new Coffee();
c= new CoffeeWithLogging(c);
await c.Prepare();



namespace CCDemo;

internal interface ICoffee
{
    //for the moment does not work for properties in interface
    //string? Name { get; set; }
    Task<bool> Prepare();

    string[] GetIngredients();
}


namespace CCDemo;
internal class Coffee : ICoffee
{
    public string? Name { get; set; }
    public async Task<bool> Prepare()
    {
        Console.WriteLine("start prepare coffee");
        await Task.Delay(1000);
        Console.WriteLine("finish prepare coffee");
        return true;
    }
    public string[] GetIngredients() => new[] { "water", "coffee" };

}



using Copycat;

namespace CCDemo;
[Decorate]
internal partial class CoffeeWithLogging: ICoffee
{
    [Template]
    private string[] AddLogging(Func<string[]> action)
    {
        try
        {
            Console.WriteLine($"start logging {nameof(action)}  ");
            return action();
        }
        catch (Exception e)
        {
            Console.WriteLine($"exception  {nameof(action)} ");
            throw;
        }
        finally
        {
               Console.WriteLine($"end logging {nameof(action)} ");
        }
    }


    [Template]
    public async Task<bool> AddLogging(Func<Task<bool>> action)       
    {
        try
        {
            Console.WriteLine($"start logging {nameof(action)} ");
            return await action();
        }
        catch (Exception e)
        {
            Console.WriteLine($"exception  {nameof(action)} ");
            throw;
        }
        finally
        {
            Console.WriteLine($"end logging {nameof(action)} ");
        }
    }
}


 

The code that is generated is

// <auto-generated/>
using Copycat;

namespace CCDemo;
internal partial class CoffeeWithLogging
{
    private CCDemo.ICoffee _decorated;
    public CoffeeWithLogging(CCDemo.ICoffee decorated)
    {
        _decorated = decorated;
    }

    /// <see cref = "CoffeeWithLogging.AddLogging(Func{Task{bool}})"/>
    public async //for the moment does not work for properties in interface
    //string? Name { get; set; }
    Task<bool> Prepare()
    {
        try
        {
            Console.WriteLine($"start logging {nameof(Prepare)} ");
            return await _decorated.Prepare();
        }
        catch (Exception e)
        {
            Console.WriteLine($"exception  {nameof(Prepare)} ");
            throw;
        }
        finally
        {
            Console.WriteLine($"end logging {nameof(Prepare)} ");
        }
    }

    /// <see cref = "CoffeeWithLogging.AddLogging(Func{string[]})"/>
    public string[] GetIngredients()
    {
        try
        {
            Console.WriteLine($"start logging {nameof(GetIngredients)}  ");
            return _decorated.GetIngredients();
        }
        catch (Exception e)
        {
            Console.WriteLine($"exception  {nameof(GetIngredients)} ");
            throw;
        }
        finally
        {
            Console.WriteLine($"end logging {nameof(GetIngredients)} ");
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/CopyCat

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.