Category: .NET

RSCG – JsonPolymorphicGenerator

RSCG – JsonPolymorphicGenerator
 
 

name JsonPolymorphicGenerator
nuget https://www.nuget.org/packages/GoLive.Generator.JsonPolymorphicGenerator/
link https://github.com/surgicalcoder/JsonPolymorphicGenerator
author surgicalcoder

Generating JsonDerivedType to be added to the base class

 

This is how you can use JsonPolymorphicGenerator .

The code that you start with is


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

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

  <ItemGroup>
    <PackageReference Include="GoLive.Generator.JsonPolymorphicGenerator" Version="1.0.4">
      <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


//https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-7-0
using JsonPolymorphicGeneratorDemo;
using System.Text.Json;

Person[] persons = new Person[2];
persons[0] = new Student() { Name="Student Ignat"};

persons[1] = new Teacher() { Name = "Teacher Ignat" };
JsonSerializerOptions opt = new ()
{
    WriteIndented = true
};
var ser = JsonSerializer.Serialize(persons, opt);
Console.WriteLine(ser);
var p = JsonSerializer.Deserialize<Person[]>(ser);
if(p != null)
foreach (var item in p)
{
    Console.WriteLine(item.Data());
}


using System.Text.Json.Serialization;

namespace JsonPolymorphicGeneratorDemo;

[JsonPolymorphic]
public abstract partial class Person
{
    
    public string? Name { get; set; }
    public abstract string Data();
}

public class Teacher : Person
{
    public override string Data()
    {
        return "Class Teacher:" + Name;
    }
}
public class Student : Person
{
    public override string Data()
    {
        return "Class Student:" + Name;
    }
}


 

The code that is generated is

using System.Text.Json.Serialization;

namespace JsonPolymorphicGeneratorDemo
{
    [JsonDerivedType(typeof(JsonPolymorphicGeneratorDemo.Teacher), "Teacher")]
    [JsonDerivedType(typeof(JsonPolymorphicGeneratorDemo.Student), "Student")]
    public partial class Person
    {
    }
}



Code and pdf at

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

RSCG – BuilderGenerator

RSCG – BuilderGenerator
 
 

name BuilderGenerator
nuget https://www.nuget.org/packages/BuilderGenerator/
link https://github.com/MelGrubb/BuilderGenerator
author Mell Grubb

Generating Builder class for an object

 

This is how you can use BuilderGenerator .

The code that you start with is


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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
  </PropertyGroup>

	  <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>

	  <ItemGroup>
	    <PackageReference Include="BuilderGenerator" Version="2.3.0" />
	  </ItemGroup>

</Project>


The code that you will use is


using Builder;

var pOld = new Person();
pOld.FirstName = "Andrei";
pOld.LastName = "Ignat";
pOld.MiddleName = "G";
var build = new PersonBuilder()
    .WithFirstName(pOld.FirstName)
    .WithMiddleName("")
    .WithLastName(pOld.LastName)
    ;
    
var pNew = build.Build();
System.Console.WriteLine(pNew.FullName());
System.Console.WriteLine(pOld.FullName());



namespace Builder;
public class Person
{
    public string FirstName { get; set; }
    public string? MiddleName { get; set; }
    public string LastName { get; set; }

    public string FullName()
    {
        return FirstName + " " + MiddleName + " "+LastName;
    }
    
}



namespace Builder;

[BuilderGenerator.BuilderFor(typeof(Person))]
public partial class PersonBuilder
{
}

 

The code that is generated is

#nullable disable

namespace BuilderGenerator
{
    /// <summary>Base class for object builder classes.</summary>
    /// <typeparam name="T">The type of the objects built by this builder.</typeparam>
    public abstract class Builder<T> where T : class
    {
        /// <summary>Gets or sets the object returned by this builder.</summary>
        /// <value>The constructed object.</value>
        #pragma warning disable CA1720 // Identifier contains type name
        protected System.Lazy<T> Object { get; set; }
        #pragma warning restore CA1720 // Identifier contains type name

        /// <summary>Builds the object instance.</summary>
        /// <returns>The constructed object.</returns>
        public abstract T Build();

        protected virtual void PostProcess(T value)
        {
        }

        /// <summary>Sets the object to be returned by this instance.</summary>
        /// <param name="value">The object to be returned.</param>
        /// <returns>A reference to this builder instance.</returns>
        public Builder<T> WithObject(T value)
        {
            Object = new System.Lazy<T>(() => value);

            return this;
        }
    }
}

namespace BuilderGenerator
{
    [System.AttributeUsage(System.AttributeTargets.Class)]
    public class BuilderForAttribute : System.Attribute
    {
        public bool IncludeInternals { get; }
        public System.Type Type { get; }

        public BuilderForAttribute(System.Type type, bool includeInternals = false)
        {
            IncludeInternals = includeInternals;
            Type = type;
        }
    }
}

#nullable disable

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by BuilderGenerator at 2023-10-02T22:28:35 in 10.3936ms.
// </auto-generated>
//------------------------------------------------------------------------------
using System.CodeDom.Compiler;


namespace Builder
{
    public partial class PersonBuilder : BuilderGenerator.Builder<Builder.Person>
    {
        public System.Lazy<string> FirstName = new System.Lazy<string>(() => default(string));
        public System.Lazy<string> LastName = new System.Lazy<string>(() => default(string));
        public System.Lazy<string?> MiddleName = new System.Lazy<string?>(() => default(string?));

        public override Builder.Person Build()
        {
            if (Object?.IsValueCreated != true)
            {
                Object = new System.Lazy<Builder.Person>(() =>
                {
                    var result = new Builder.Person
                    {
                        FirstName = FirstName.Value,
                        LastName = LastName.Value,
                        MiddleName = MiddleName.Value,
                    };

                    return result;
                });

                PostProcess(Object.Value);
            }

            return Object.Value;
        }

        public PersonBuilder WithFirstName(string value)
        {
            return WithFirstName(() => value);
        }

        public PersonBuilder WithFirstName(System.Func<string> func)
        {
            FirstName = new System.Lazy<string>(func);
            return this;
        }

        public PersonBuilder WithoutFirstName()
        {
            FirstName = new System.Lazy<string>(() => default(string));
            return this;
        }

        public PersonBuilder WithLastName(string value)
        {
            return WithLastName(() => value);
        }

        public PersonBuilder WithLastName(System.Func<string> func)
        {
            LastName = new System.Lazy<string>(func);
            return this;
        }

        public PersonBuilder WithoutLastName()
        {
            LastName = new System.Lazy<string>(() => default(string));
            return this;
        }

        public PersonBuilder WithMiddleName(string? value)
        {
            return WithMiddleName(() => value);
        }

        public PersonBuilder WithMiddleName(System.Func<string?> func)
        {
            MiddleName = new System.Lazy<string?>(func);
            return this;
        }

        public PersonBuilder WithoutMiddleName()
        {
            MiddleName = new System.Lazy<string?>(() => default(string?));
            return this;
        }
    }
}

Code and pdf at

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

RSCG – Disposer

RSCG – Disposer
 
 

name Disposer
nuget https://www.nuget.org/packages/Disposer/
link https://github.com/HakamFostok/Disposer
author Hakan Fıstık

Generates partials for dispose resources

 

This is how you can use Disposer .

The code that you start with is


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

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

  <ItemGroup>
	  <PackageReference Include="Disposer" Version="1.0.4" PrivateAssets="all" />
    
  </ItemGroup>
	 <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>

</Project>


The code that you will use is


using IDisposableGeneratorDemo;
//https://github.com/benutomo-dev/RoslynComponents
using (var db = new DALDB())
{
    Console.WriteLine("before releasing");
}
Console.WriteLine("after releasing");


namespace IDisposableGeneratorDemo;

class ConnectionDB : IDisposable
{
    public void Dispose()
    {
        Console.WriteLine("disposing connectiondb");
    }
}



namespace IDisposableGeneratorDemo;


[Disposer.Disposable]
partial class DALDB :IDisposable
{
    
    private readonly ConnectionDB cn;
    private readonly ConnectionDB cn1;

    public DALDB()
    {
        cn = new ConnectionDB();
        cn1=new ConnectionDB();
    }

    partial void DisposeManaged()
    {
        cn.Dispose();
        cn1.Dispose();
    }

    partial void DisposeUnmanaged()
    {
        // free Unmanaged resources here
    }
}


 

The code that is generated is

#pragma warning disable CS0436
#nullable enable

namespace Benutomo
{
    /// <summary>
    /// 指定したクラスに破棄(<see cref=""System.IDisposable"" />,<see cref=""System.IAsyncDisposable"" />)をサポートするメンバを破棄する<see cref=""System.IDisposable.Dispose"" />メソッドおよび<see cref=""System.IAsyncDisposable.DisposeAsync"" />メソッド(当該クラスに<see cref=""System.IAsyncDisposable"" />インターフェイスが含まれている場合のみ)を自動実装する。
    /// </summary>
    [global::System.AttributeUsage(global::System.AttributeTargets.Class)]
    internal class AutomaticDisposeImplAttribute : global::System.Attribute
    {
        /// <summary>
        /// 自動破棄実装の既定動作を設定する。
        /// </summary>
        public AutomaticDisposeImplMode Mode { get; set; }
    }
}
#pragma warning disable CS0436
#nullable enable

namespace Benutomo
{
    /// <summary>
    /// 破棄(<see cref=""System.IDisposable"" />,<see cref=""System.IAsyncDisposable"" />)をサポートするメンバを自動実装Disposeの対象とすることに関する振る舞いの指定。
    /// </summary>
    internal enum AutomaticDisposeImplMode
    {
        /// <summary>
        /// <see cref=""System.IDisposable"" />,<see cref=""System.IAsyncDisposable"" />を継承する型を持つメンバは暗黙的に自動Dispose呼び出しの対象となる。
        /// </summary>
        Implicit,

        /// <summary>
        /// <see cref=""System.IDisposable"" />,<see cref=""System.IAsyncDisposable"" />を継承する型を持つメンバは自動Dispose呼び出しの対象となる。
        /// </summary>
        Explicit,
    }
}
#pragma warning disable CS0436
#nullable enable

namespace Benutomo
{
    /// <summary>
    /// このメンバに対して、<see cref=""System.IDisposable.Dispose"" />メソッドまたは<see cref=""System.IAsyncDisposable.DisposeAsync"" />メソッドの自動呼出しは行いません。このオブジェクトで破棄するのが不適当であるかユーザ自身が<see cref=""System.IDisposable.Dispose"" />メソッドまたは<see cref=""System.IAsyncDisposable.DisposeAsync"" />メソッドの呼び出しを実装するメンバです。
    /// </summary>
    [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property)]
    internal class DisableAutomaticDisposeAttribute : global::System.Attribute
    {
    }
}
#pragma warning disable CS0436
#nullable enable

namespace Benutomo
{
    /// <summary>
    /// このオブジェクトの破棄と同時に自動的に<see cref=""System.IDisposable.Dispose"" />メソッドまたは<see cref=""System.IAsyncDisposable.DisposeAsync"" />メソッドを呼び出します。
    /// </summary>
    [global::System.AttributeUsage(global::System.AttributeTargets.Field | global::System.AttributeTargets.Property)]
    internal class EnableAutomaticDisposeAttribute : global::System.Attribute
    {
        public EnableAutomaticDisposeAttribute() { }

        /// <summary>
        /// このオブジェクトの破棄と同時に自動的に<see cref=""System.IDisposable.Dispose"" />メソッドまたは<see cref=""System.IAsyncDisposable.DisposeAsync"" />メソッドを呼び出します。
        /// </summary>
        /// <param name=""linkedMembers"">このメンバの破棄に連動して破棄されるメンバ(ここで列挙されたメンバはEnable/DisableAutomaticDispose属性を省略可能)</param>
        public EnableAutomaticDisposeAttribute(params string[] dependencyMembers) { }
    }
}
#nullable enable
#pragma warning disable CS0612,CS0618,CS0619
namespace IDisposableGeneratorDemo
{
    partial class DALDB // This is implementation class by AutomaticDisposeImpl.
    {
        [global::System.ComponentModel.Browsable(false)]
        [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
        [global::System.Obsolete("AutomaticDisposeImplによって生成されたフィールドです。一般のコードから参照してはいけません。")]
        private const int __generator_internal_BeNotInitiatedAnyDispose = 0;
        [global::System.ComponentModel.Browsable(false)]
        [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
        [global::System.Obsolete("AutomaticDisposeImplによって生成されたフィールドです。一般のコードから参照してはいけません。")]
        private const int __generator_internal_InitiatedSyncDispose  = 1;
        [global::System.ComponentModel.Browsable(false)]
        [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
        [global::System.Obsolete("AutomaticDisposeImplによって生成されたフィールドです。一般のコードから参照してはいけません。")]
        private const int __generator_internal_InitiatedAsyncDispose = 2;
        [global::System.ComponentModel.Browsable(false)]
        [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
        [global::System.Obsolete("AutomaticDisposeImplによって生成されたフィールドです。一般のコードから参照してはいけません。")]
        private const int __generator_internal_DisposeAlreadyCompleted = 9;
        [global::System.ComponentModel.Browsable(false)]
        [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
        [global::System.Obsolete("AutomaticDisposeImplによって生成されたフィールドです。一般のコードから参照してはいけません。")]
        private int __generator_internal_disposeState = __generator_internal_BeNotInitiatedAnyDispose;

        public bool IsDisposed => (global::System.Threading.Thread.VolatileRead(ref __generator_internal_disposeState) != __generator_internal_BeNotInitiatedAnyDispose);

        [global::System.ComponentModel.Browsable(false)]
        [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
        [global::System.Obsolete("AutomaticDisposeImplによって生成されたフィールドです。一般のコードから参照してはいけません。")]
        private int __generator_internal_managedObjectDisposeState = 0;

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                var managedObjectDisposeState = global::System.Threading.Interlocked.Exchange(ref __generator_internal_managedObjectDisposeState, 1);
                if (managedObjectDisposeState == 0)
                {
                    try
                    {
                        (this.cn as global::System.IDisposable)?.Dispose();
                    }
                    catch (global::System.Exception ex)
                    {
                        global::System.Diagnostics.Debug.Fail($"Caught an exception in the cn.Dispose() calling. Message=\"{ex.Message}\"");
                    }
                    try
                    {
                        (this.cn1 as global::System.IDisposable)?.Dispose();
                    }
                    catch (global::System.Exception ex)
                    {
                        global::System.Diagnostics.Debug.Fail($"Caught an exception in the cn1.Dispose() calling. Message=\"{ex.Message}\"");
                    }
                }
            }
        }

        public void Dispose()
        {
            var dispose_state = global::System.Threading.Interlocked.CompareExchange(ref __generator_internal_disposeState, __generator_internal_InitiatedSyncDispose, __generator_internal_BeNotInitiatedAnyDispose);
            if (dispose_state == __generator_internal_BeNotInitiatedAnyDispose)
            {

                // Dispose managed members and release unmaneged resources.
                Dispose(disposing: true);

                global::System.Threading.Thread.VolatileWrite(ref __generator_internal_disposeState, __generator_internal_DisposeAlreadyCompleted);
            }
        }
    }
}

#pragma warning disable CS0436
#nullable enable

namespace Benutomo
{
    /// <summary>
    /// <see cref=""Benutomo.AutomaticDisposeImplAttribute""/>を利用しているクラスで、ユーザが実装するマネージドオブジェクトを非同期的な処理による破棄を行うメソッドに付与する。このメソッドはデストラクタからは呼び出されない。デストラクタからも呼び出される必要がある場合はデストラクタで必要な処理を全て同期的に行うようにした上で<see cref=""Benutomo.UnmanagedResourceReleaseMethodAttribute"">を使用すること。この属性を付与するメソッドは引数なしで戻り値は<see cref=""System.Threading.ValueTask"" />などawait可能な型である必要がある。このメソッドはこのオブジェクトのDisposeAsync()が初めて実行された時に自動実装コードから呼び出される。ただし、このメソッドを所有するクラスがIDisposableも実装していて、かつ、Dispose()によってこのオブジェクトが破棄された場合は、この属性が付与されているメソッドは呼び出されず、<see cref=""Benutomo.ManagedObjectDisposeMethodAttribute"">が付与されているメソッドが呼び出される。
    /// </summary>
    [global::System.AttributeUsage(global::System.AttributeTargets.Method)]
    internal class ManagedObjectAsyncDisposeMethodAttribute : global::System.Attribute
    {
        /// <summary>
        /// <inheritdoc cref=""Benutomo.ManagedObjectAsyncDisposeMethodAttribute""/>
        /// </summary>
        public ManagedObjectAsyncDisposeMethodAttribute() { }
    }
}
#pragma warning disable CS0436
#nullable enable

namespace Benutomo
{
    /// <summary>
    /// <see cref=""Benutomo.AutomaticDisposeImplAttribute""/>を利用しているクラスで、ユーザが実装するマネージドオブジェクトを同期的な処理による破棄を行うメソッドに付与する。このメソッドはデストラクタからは呼び出されない。デストラクタからも呼び出される必要がある場合は<see cref=""Benutomo.UnmanagedResourceReleaseMethodAttribute"">を使用すること。この属性を付与するメソッドは引数なしで戻り値はvoidである必要がある。このメソッドはこのオブジェクトのDispose()が初めて実行された時に自動実装コードから呼び出される。ただし、このメソッドを所有するクラスがIAsyncDisposableも実装していて、かつ、DisposeAsync()によってこのオブジェクトが破棄された場合は、この属性が付与されているメソッドは呼び出されず、<see cref=""Benutomo.ManagedObjectAsyncDisposeMethodAttribute"">が付与されているメソッドが呼び出される。
    /// </summary>
    [global::System.AttributeUsage(global::System.AttributeTargets.Method)]
    internal class ManagedObjectDisposeMethodAttribute : global::System.Attribute
    {
        /// <summary>
        /// <inheritdoc cref=""Benutomo.ManagedObjectDisposeMethodAttribute""/>
        /// </summary>
        public ManagedObjectDisposeMethodAttribute() { }
    }
}
#pragma warning disable CS0436
#nullable enable

namespace Benutomo
{
    /// <summary>
    /// <see cref=""Benutomo.AutomaticDisposeImplAttribute""/>を利用しているクラスで、ユーザが実装するアンマネージドリソースの解放を行うメソッド(引数なしで戻り値はvoid)に付与する。このメソッドはこのオブジェクトのDispose()またはDisposeAsync()、デストラクタのいずれかが初めて実行された時に自動実装コードから呼び出される。この属性を付与したメソッドは、実装者の責任でGCのファイナライズスレッドから呼び出されても問題無いように実装しなければならないことに注意すること。
    /// </summary>
    [global::System.AttributeUsage(global::System.AttributeTargets.Method)]
    internal class UnmanagedResourceReleaseMethodAttribute : global::System.Attribute
    {
        /// <summary>
        /// <inheritdoc cref=""Benutomo.UnmanagedResourceReleaseMethodAttribute""/>
        /// </summary>
        public UnmanagedResourceReleaseMethodAttribute() { }
    }
}
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the Disposer source generator
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace IDisposableGeneratorDemo
{
    partial class DALDB : global::System.IDisposable
    {
        partial void DisposeManaged();
        partial void DisposeUnmanaged();

        private bool disposed = false;

        ~DALDB()
        {
            Dispose(false);
        }

        private void Dispose(bool disposing)
        {
            if (disposed)
                return;

            if (disposing)
            {
                DisposeManaged();
            }

            DisposeUnmanaged();

            disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            global::System.GC.SuppressFinalize(this);
        }
    }
}
// <autogenerated/>
namespace IDisposableGeneratorDemo;

// <autogenerated/>
#pragma warning disable SA1636, 8618
namespace IDisposableGenerator
{
    using System;

    // used only by a source generator to generate Dispose() and Dispose(bool).
    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    internal class CallOnDisposeAttribute : Attribute
    {
        public CallOnDisposeAttribute()
        {
        }
    }

    // used only by a source generator to generate Dispose() and Dispose(bool).
    [AttributeUsage(AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    internal class DisposeFieldAttribute : Attribute
    {
        public DisposeFieldAttribute(bool owner)
        {
        }
    }

    // used only by a source generator to generate Dispose() and Dispose(bool).
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    internal class GenerateDisposeAttribute : Attribute
    {
        public GenerateDisposeAttribute(bool stream)
        {
        }
    }

    // used only by a source generator to generate Dispose() and Dispose(bool).
    [AttributeUsage(AttributeTargets.Event | AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    internal class NullOnDisposeAttribute : Attribute
    {
        public NullOnDisposeAttribute()
        {
        }
    }
}
#pragma warning restore SA1636, 8618

Code and pdf at

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

RSCG – ResXGenerator

RSCG – ResXGenerator
 
 

name ResXGenerator
nuget https://www.nuget.org/packages/Aigamo.ResXGenerator/
link https://github.com/ycanardeau/ResXGenerator
author Aigamo

Resources as string

 

This is how you can use ResXGenerator .

The code that you start with is


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

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

	<ItemGroup>
		<PackageReference Include="Aigamo.ResXGenerator" Version="4.2.0">
			<PrivateAssets>all</PrivateAssets>
			<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
		</PackageReference>
	</ItemGroup>

	<ItemGroup>
		<Compile Update="GenResources.Designer.cs">
		  <DesignTime>True</DesignTime>
		  <AutoGen>True</AutoGen>
		  <DependentUpon>GenResources.resx</DependentUpon>
		</Compile>
		<Compile Update="GenResources.resx">
			<GenerateCode>true</GenerateCode>					
			<GenerateResource>false</GenerateResource>
			<PublicClass>true</PublicClass>
		</Compile>

	</ItemGroup>

	<ItemGroup>
	  <EmbeddedResource Update="GenResources.resx">
	    <Generator>PublicResXFileCodeGenerator</Generator>
	    <LastGenOutput>GenResources.Designer.cs</LastGenOutput>
	  </EmbeddedResource>
	</ItemGroup>
	<PropertyGroup>
		<ResXGenerator_GenerateCode>true</ResXGenerator_GenerateCode>
		<ResXGenerator_ClassNamePostfix>Model</ResXGenerator_ClassNamePostfix>		
	</PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>

</Project>


The code that you will use is


Console.WriteLine(ResXDemo.GenResourcesModel.MyName);
Console.WriteLine(ResXDemo.GenResources.MyName);




<?xml version="1.0" encoding="utf-8"?>
<root>
  <!-- 
    Microsoft ResX Schema 
    
    Version 2.0
    
    The primary goals of this format is to allow a simple XML format 
    that is mostly human readable. The generation and parsing of the 
    various data types are done through the TypeConverter classes 
    associated with the data types.
    
    Example:
    
    ... ado.net/XML headers & schema ...
    <resheader name="resmimetype">text/microsoft-resx</resheader>
    <resheader name="version">2.0</resheader>
    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>[base64 mime encoded serialized .NET Framework object]</value>
    </data>
    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
        <comment>This is a comment</comment>
    </data>
                
    There are any number of "resheader" rows that contain simple 
    name/value pairs.
    
    Each data row contains a name, and value. The row also contains a 
    type or mimetype. Type corresponds to a .NET class that support 
    text/value conversion through the TypeConverter architecture. 
    Classes that don't support this are serialized and stored with the 
    mimetype set.
    
    The mimetype is used for serialized objects, and tells the 
    ResXResourceReader how to depersist the object. This is currently not 
    extensible. For a given mimetype the value must be set accordingly:
    
    Note - application/x-microsoft.net.object.binary.base64 is the format 
    that the ResXResourceWriter will generate, however the reader can 
    read any of the formats listed below.
    
    mimetype: application/x-microsoft.net.object.binary.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
            : and then encoded with base64 encoding.
    
    mimetype: application/x-microsoft.net.object.soap.base64
    value   : The object must be serialized with 
            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
            : and then encoded with base64 encoding.

    mimetype: application/x-microsoft.net.object.bytearray.base64
    value   : The object must be serialized into a byte array 
            : using a System.ComponentModel.TypeConverter
            : and then encoded with base64 encoding.
    -->
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="MyName" xml:space="preserve">
    <value>Andrei Ignat {x}</value>
  </data>
</root>


//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace ResXDemo {
    using System;
    
    
    /// <summary>
    ///   A strongly-typed resource class, for looking up localized strings, etc.
    /// </summary>
    // This class was auto-generated by the StronglyTypedResourceBuilder
    // class via a tool like ResGen or Visual Studio.
    // To add or remove a member, edit your .ResX file then rerun ResGen
    // with the /str option, or rebuild your VS project.
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    public class GenResources {
        
        private static global::System.Resources.ResourceManager resourceMan;
        
        private static global::System.Globalization.CultureInfo resourceCulture;
        
        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
        internal GenResources() {
        }
        
        /// <summary>
        ///   Returns the cached ResourceManager instance used by this class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        public static global::System.Resources.ResourceManager ResourceManager {
            get {
                if (object.ReferenceEquals(resourceMan, null)) {
                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ResXDemo.GenResources", typeof(GenResources).Assembly);
                    resourceMan = temp;
                }
                return resourceMan;
            }
        }
        
        /// <summary>
        ///   Overrides the current thread's CurrentUICulture property for all
        ///   resource lookups using this strongly typed resource class.
        /// </summary>
        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
        public static global::System.Globalization.CultureInfo Culture {
            get {
                return resourceCulture;
            }
            set {
                resourceCulture = value;
            }
        }
        
        /// <summary>
        ///   Looks up a localized string similar to Andrei Ignat {x}.
        /// </summary>
        public static string MyName {
            get {
                return ResourceManager.GetString("MyName", resourceCulture);
            }
        }
    }
}


 

The code that is generated is

// ------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
#nullable enable
namespace Aigamo.ResXGenerator;
internal static partial class Helpers
{
    public static string GetString_(string fallback) => System.Globalization.CultureInfo.CurrentUICulture.LCID switch
    {
        _ => fallback
    };
}

// ------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
#nullable enable
namespace ResXDemo;
using static Aigamo.ResXGenerator.Helpers;

internal static class GenResourcesModel
{

    /// <summary>
    /// Looks up a localized string similar to Andrei Ignat {x}.
    /// </summary>
    public static string? MyName => GetString_("Andrei Ignat {x}");
}

Code and pdf at

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

RSCG – RSCG_Decorator

RSCG – RSCG_Decorator
 
 

name RSCG_Decorator
nuget https://www.nuget.org/packages/RSCG_Decorator/
link https://github.com/ignatandrei/RSCG_Decorator
author Andrei Ignat

Intercept methods – start, stop,exception

 

This is how you can use RSCG_Decorator .

The code that you start with is


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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
	  <IsPackable>false</IsPackable>
  </PropertyGroup>

  <PropertyGroup>
    <TreatWarningsAsErrors>True</TreatWarningsAsErrors>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
  </ItemGroup>

  <ItemGroup>
	  <PackageReference Include="RSCG_Decorator" Version="7.2023.930.2116" OutputItemType="Analyzer" ReferenceOutputAssembly="false"  />
	  <PackageReference Include="RSCG_DecoratorCommon" Version="7.2023.930.2116" />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is



var serviceCollection = new ServiceCollection()
          .AddLogging(builder =>
        builder.AddSimpleConsole(options =>
        {
            options.IncludeScopes = true;
            options.SingleLine = true;
            options.TimestampFormat = "HH:mm:ss ";
        }))
          .AddTransient<IPerson, Person>();

//register here the decorator
    serviceCollection = serviceCollection
        .AddTransient<Person, Person>()
        .AddTransient<IPerson, Person_Decorator>();

var serviceProvider=serviceCollection.BuildServiceProvider();

ArgumentNullException.ThrowIfNull(serviceProvider);

var logger = serviceProvider.GetRequiredService<ILoggerFactory>()
    .CreateLogger<Program>();


//using (logger.BeginScope("[scope is enabled]"))
//{
//    logger.LogInformation("Hello World!");
//}
logger.LogInformation("Starting app!");

var data = serviceProvider.GetRequiredService<IPerson>();
data.FirstName = "Andrei";
data.LastName = "Ignat";

Console.WriteLine(data.GetType().FullName);
Console.WriteLine( data.FullName("|"));

try
{
    await data.SaveId(-100);
}
catch(Exception ex)
{
    logger.LogError(ex, "in the main program");
}
//Console.ReadLine();

public partial class Program
{

}


using RSCG_DecoratorCommon;

namespace RSCG_DecoratorTestConsole;
public partial class Person : IDecoratorMethodV1
{
    public void EndMethod(MethodRecognizer recognizer)
    {
        logger.LogInformation("end "+recognizer.UniqueId);
    }

   
    public void ExceptionMethod(Exception ex, MethodRecognizer recognizer)
    {
        logger.LogError(ex, "exception on " + recognizer.UniqueId+ " Value Parameters:" + recognizer.ValueTypeParametersString); 
    }


    public void StartMethod(MethodRecognizer recognizer)
    {
        logger.LogInformation("start " + recognizer.UniqueId + " Value Parameters:"+recognizer.ValueTypeParametersString);
   }
}



using Microsoft.Extensions.Logging;
using System.Text;

namespace RSCG_DecoratorTestConsole;

public partial  class Person : IPerson 
{
    internal readonly ILogger<Person> logger;    
    public Person(ILogger<Person> logger)
    {
        this.logger = logger;
    }
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public string FullName(string separator=" ")
    {
        logger.LogInformation("from original method");
        return FirstName+separator+LastName;
    }
    public void DisplayNameOnConsole()
    {
        Console.WriteLine(FullName());
    }
    public async Task<string> GetName()
    {
        await Task.Delay(1000);
        return FirstName??"";
    }
    public Task<string> GetFullName()
    {
        return Task.FromResult( FullName());
    }
    public Task SaveId(int id)
    {
        if (id < 0)
        {
            throw new ArgumentException("this is an error because is <0 ");
        }
        return Task.CompletedTask;
    }
}


 

The code that is generated is

// <auto-generated/>
#nullable enable

namespace RSCG_Decorator.DecoratorRecognizers;
internal interface IDecoratorMethodV1
{
    void StartMethod(MethodRecognizer recognizer);
    void ExceptionMethod(System.Exception ex, MethodRecognizer recognizer);
    void EndMethod(MethodRecognizer recognizer);
}
// <auto-generated/>
#nullable enable

namespace RSCG_Decorator.DecoratorRecognizers;
internal struct MethodRecognizer
{
    public MethodRecognizer(string nameClass, string nameMethod)
    {
        NameClass = nameClass;
        NameMethod = nameMethod;
    }

    public string? FileName { get; set; }
    public int line { get; set; }
    public string NameClass { get; }
    public string NameMethod { get; }

    public string UniqueId
    {
        get
        {
            return $"Class:{NameClass} Method:{NameMethod} File:{FileName} Line:{line}";
        }
    }
}
//generated by RSCG_Decorator, version 7.2023.930.2116
namespace RSCG_DecoratorTestConsole {
    partial class Person_Decorator :RSCG_DecoratorTestConsole.IPerson {
        private Person original;
        public Person_Decorator (Person original ){
            this.original=original;
        }
        //now decorate methods : 5


        public string? FirstName {
            get{
        return original.FirstName;
        }
        set{
        original.FirstName=value;
    }            
            
} 
    
        public string? LastName {
            get{
        return original.LastName;
        }
        set{
        original.LastName=value;
    }            
            
} 
    
        /*
        FullName 
        */
        public string FullName(string separator = " ")
        {
        var FullName_14 =new RSCG_DecoratorCommon.MethodRecognizer("Person","FullName");
        FullName_14.FileName="C:\\gth\\RSCG_Examples\\v2\\rscg_examples\\Decorator\\src\\RSCG_DecoratorTestConsole\\Person.cs";
        FullName_14.Line=14;

            FullName_14.ValueTypeParameters.Add("separator", separator);
                    using var mrUtils= new RSCG_DecoratorCommon.MRUtils(FullName_14, original);
        try{
             return original.FullName(separator);
        }
        catch(Exception ex){
        mrUtils.SendException(ex);
            throw;
        }
        
        }
        
    
        /*
        DisplayNameOnConsole 
        */
        public void DisplayNameOnConsole()
        {
        var DisplayNameOnConsole_19 =new RSCG_DecoratorCommon.MethodRecognizer("Person","DisplayNameOnConsole");
        DisplayNameOnConsole_19.FileName="C:\\gth\\RSCG_Examples\\v2\\rscg_examples\\Decorator\\src\\RSCG_DecoratorTestConsole\\Person.cs";
        DisplayNameOnConsole_19.Line=19;
        using var mrUtils= new RSCG_DecoratorCommon.MRUtils(DisplayNameOnConsole_19, original);
        try{
            original.DisplayNameOnConsole();
        }
        catch(Exception ex){
        mrUtils.SendException(ex);
            throw;
        }
        
        }
        
    
        /*
        GetName 
        */
        public async System.Threading.Tasks.Task<string> GetName()
        {
        var GetName_23 =new RSCG_DecoratorCommon.MethodRecognizer("Person","GetName");
        GetName_23.FileName="C:\\gth\\RSCG_Examples\\v2\\rscg_examples\\Decorator\\src\\RSCG_DecoratorTestConsole\\Person.cs";
        GetName_23.Line=23;
        using var mrUtils= new RSCG_DecoratorCommon.MRUtils(GetName_23, original);
        try{
            return await original.GetName();
        }
        catch(Exception ex){
        mrUtils.SendException(ex);
            throw;
        }
        
        }
        
    
        /*
        GetFullName 
        */
        public async System.Threading.Tasks.Task<string> GetFullName()
        {
        var GetFullName_28 =new RSCG_DecoratorCommon.MethodRecognizer("Person","GetFullName");
        GetFullName_28.FileName="C:\\gth\\RSCG_Examples\\v2\\rscg_examples\\Decorator\\src\\RSCG_DecoratorTestConsole\\Person.cs";
        GetFullName_28.Line=28;
        using var mrUtils= new RSCG_DecoratorCommon.MRUtils(GetFullName_28, original);
        try{
            return await original.GetFullName();
        }
        catch(Exception ex){
        mrUtils.SendException(ex);
            throw;
        }
        
        }
        
    
        /*
        SaveId 
        */
        public async System.Threading.Tasks.Task SaveId(int id)
        {
        var SaveId_32 =new RSCG_DecoratorCommon.MethodRecognizer("Person","SaveId");
        SaveId_32.FileName="C:\\gth\\RSCG_Examples\\v2\\rscg_examples\\Decorator\\src\\RSCG_DecoratorTestConsole\\Person.cs";
        SaveId_32.Line=32;

            SaveId_32.ValueTypeParameters.Add("id", id);
                    using var mrUtils= new RSCG_DecoratorCommon.MRUtils(SaveId_32, original);
        try{
            await original.SaveId(id);
        }
        catch(Exception ex){
        mrUtils.SendException(ex);
            throw;
        }
        
        }
        
    
    }
}


Code and pdf at

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

RSCG – ProtobufSourceGenerator

RSCG – ProtobufSourceGenerator
 
 

name ProtobufSourceGenerator
nuget https://www.nuget.org/packages/LaDeak.ProtobufSourceGenerator/
link https://github.com/ladeak/ProtobufSourceGenerator
author Laszlo Deak

Serializing a class to protobuf

 

This is how you can use ProtobufSourceGenerator .

The code that you start with is


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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
	<ItemGroup>
		<PackageReference Include="LaDeak.ProtobufSourceGenerator" Version="1.5.1" OutputItemType="Analyzer" ReferenceOutputAssembly="true" />
		<PackageReference Include="protobuf-net" Version="3.2.26" />
	</ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using ProtoBuf;
using ProtobufSourceGeneratorDemo;

using var ms = new MemoryStream();
Serializer.Serialize(ms, new Person() { Name= "Andrei Ignat" });
ms.Seek(0, SeekOrigin.Begin);
var entity = Serializer.Deserialize<Person>(ms);
Console.WriteLine("name is "+entity.Name);


using ProtoBuf;

namespace ProtobufSourceGeneratorDemo;

[ProtoContract]
public partial class Person
{
    
    public int Id { get; set; }
    public string? Name { get; set; }
}



 

The code that is generated is

// <auto-generated/>
#nullable enable
namespace ProtobufSourceGeneratorDemo;
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
public partial class Person
{
    [global::ProtoBuf.ProtoMember(1)]
    private int ProtoId { get => Id; set => Id = value; }

    [global::ProtoBuf.ProtoMember(2)]
    private string? ProtoName { get => Name; set => Name = value; }
}

Code and pdf at

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

RSCG – SafeRouting

RSCG – SafeRouting
 
 

name SafeRouting
nuget https://www.nuget.org/packages/SafeRouting/
link https://github.com/daviddotcs/safe-routing
author David Wake

Safe Routing for MVC

 

This is how you can use SafeRouting .

The code that you start with is


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

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

  <ItemGroup>
    <PackageReference Include="SafeRouting" Version="1.4.0" />
  </ItemGroup>

	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


@using SafeRoutingDemo
@using SafeRoutingDemo.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper SafeRouting.TagHelpers.*, SafeRouting.Common



@{
    var privacy = Routes.Controllers.Home.Privacy();

}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - SafeRoutingDemo</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/SafeRoutingDemo.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container-fluid">
                <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">SafeRoutingDemo</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
                            <a for-route="privacy">!New Privacy!</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2023 - SafeRoutingDemo - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
        </div>
    </footer>
    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>


 

The code that is generated is

#pragma checksum "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Home\Index.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "2999aea4fd9585148590d2af132f38ffc044fe9b3869b38d4a2bbf6259d065ea"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Home_Index), @"mvc.1.0.view", @"/Views/Home/Index.cshtml")]
namespace AspNetCoreGeneratedDocument
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Mvc;
    using global::Microsoft.AspNetCore.Mvc.Rendering;
    using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo.Models;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/Home/Index.cshtml")]
    [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
    #nullable restore
    internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    #nullable disable
    {
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Home\Index.cshtml"
  
    ViewData["Title"] = "Home Page";

#line default
#line hidden
#nullable disable
            WriteLiteral("\r\n<div class=\"text-center\">\r\n    <h1 class=\"display-4\">Welcome</h1>\r\n    <p>Learn about <a href=\"https://docs.microsoft.com/aspnet/core\">building Web apps with ASP.NET Core</a>.</p>\r\n</div>\r\n");
        }
        #pragma warning restore 1998
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
        #nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Home\Privacy.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "0e00a4445b214863ea51c8985fae1970b43e932712216fa047faf3062bb23445"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Home_Privacy), @"mvc.1.0.view", @"/Views/Home/Privacy.cshtml")]
namespace AspNetCoreGeneratedDocument
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Mvc;
    using global::Microsoft.AspNetCore.Mvc.Rendering;
    using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo.Models;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/Home/Privacy.cshtml")]
    [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
    #nullable restore
    internal sealed class Views_Home_Privacy : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    #nullable disable
    {
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Home\Privacy.cshtml"
  
    ViewData["Title"] = "Privacy Policy";

#line default
#line hidden
#nullable disable
            WriteLiteral("<h1>");
#nullable restore
#line (4,6)-(4,23) 6 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Home\Privacy.cshtml"
Write(ViewData["Title"]);

#line default
#line hidden
#nullable disable
            WriteLiteral("</h1>\r\n\r\n<p>Use this page to detail your site\'s privacy policy.</p>\r\n");
        }
        #pragma warning restore 1998
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
        #nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\Error.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "5dbf98b6b9394ad78206edce40cab1d7a238aa69cfefa41bab0ebc6aa22488aa"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Shared_Error), @"mvc.1.0.view", @"/Views/Shared/Error.cshtml")]
namespace AspNetCoreGeneratedDocument
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Mvc;
    using global::Microsoft.AspNetCore.Mvc.Rendering;
    using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo.Models;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/Shared/Error.cshtml")]
    [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
    #nullable restore
    internal sealed class Views_Shared_Error : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<ErrorViewModel>
    #nullable disable
    {
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\Error.cshtml"
  
    ViewData["Title"] = "Error";

#line default
#line hidden
#nullable disable
            WriteLiteral("\r\n<h1 class=\"text-danger\">Error.</h1>\r\n<h2 class=\"text-danger\">An error occurred while processing your request.</h2>\r\n\r\n");
#nullable restore
#line 9 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\Error.cshtml"
 if (Model.ShowRequestId)
{

#line default
#line hidden
#nullable disable
            WriteLiteral("    <p>\r\n        <strong>Request ID:</strong> <code>");
#nullable restore
#line (12,45)-(12,60) 6 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\Error.cshtml"
Write(Model.RequestId);

#line default
#line hidden
#nullable disable
            WriteLiteral("</code>\r\n    </p>\r\n");
#nullable restore
#line 14 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\Error.cshtml"
}

#line default
#line hidden
#nullable disable
            WriteLiteral(@"
<h3>Development Mode</h3>
<p>
    Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>
    It can result in displaying sensitive information from exceptions to end users.
    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
    and restarting the app.
</p>
");
        }
        #pragma warning restore 1998
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<ErrorViewModel> Html { get; private set; } = default!;
        #nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed5"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Shared__Layout), @"mvc.1.0.view", @"/Views/Shared/_Layout.cshtml")]
namespace AspNetCoreGeneratedDocument
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Mvc;
    using global::Microsoft.AspNetCore.Mvc.Rendering;
    using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo.Models;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/Shared/_Layout.cshtml")]
    [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
    #nullable restore
    internal sealed class Views_Shared__Layout : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    #nullable disable
    {
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("rel", new global::Microsoft.AspNetCore.Html.HtmlString("stylesheet"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("href", new global::Microsoft.AspNetCore.Html.HtmlString("~/lib/bootstrap/dist/css/bootstrap.min.css"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_2 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("href", "~/css/site.css", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_3 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("href", "~/SafeRoutingDemo.styles.css", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_4 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("navbar-brand"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_5 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("asp-area", "", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_6 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("asp-controller", "Home", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_7 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("asp-action", "Index", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_8 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("class", new global::Microsoft.AspNetCore.Html.HtmlString("nav-link text-dark"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_9 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("asp-action", "Privacy", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_10 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("src", new global::Microsoft.AspNetCore.Html.HtmlString("~/lib/jquery/dist/jquery.min.js"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_11 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("src", new global::Microsoft.AspNetCore.Html.HtmlString("~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_12 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("src", "~/js/site.js", global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        #line hidden
        #pragma warning disable 0649
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
        #pragma warning restore 0649
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
        #pragma warning disable 0169
        private string __tagHelperStringValueBuffer;
        #pragma warning restore 0169
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
        {
            get
            {
                if (__backed__tagHelperScopeManager == null)
                {
                    __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
                }
                return __backed__tagHelperScopeManager;
            }
        }
        private global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_HeadTagHelper;
        private global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper;
        private global::Microsoft.AspNetCore.Mvc.TagHelpers.LinkTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper;
        private global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_BodyTagHelper;
        private global::Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper;
        private global::SafeRouting.TagHelpers.RouteValuesTagHelper __SafeRouting_TagHelpers_RouteValuesTagHelper;
        private global::Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper __Microsoft_AspNetCore_Mvc_TagHelpers_ScriptTagHelper;
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
  
    var privacy = Routes.Controllers.Home.Privacy();


#line default
#line hidden
#nullable disable
            WriteLiteral("<!DOCTYPE html>\r\n<html lang=\"en\">\r\n");
            __tagHelperExecutionContext = __tagHelperScopeManager.Begin("head", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed58642", async() => {
                WriteLiteral("\r\n    <meta charset=\"utf-8\" />\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n    <title>");
#nullable restore
#line (10,13)-(10,30) 6 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
Write(ViewData["Title"]);

#line default
#line hidden
#nullable disable
                WriteLiteral(" - SafeRoutingDemo</title>\r\n    ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("link", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed59355", async() => {
                }
                );
                __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n    ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("link", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed510557", async() => {
                }
                );
                __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
                __Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.TagHelpers.LinkTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
                __Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper.Href = (string)__tagHelperAttribute_2.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_2);
#nullable restore
#line 12 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
__Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper.AppendVersion = true;

#line default
#line hidden
#nullable disable
                __tagHelperExecutionContext.AddTagHelperAttribute("asp-append-version", __Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper.AppendVersion, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n    ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("link", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed512638", async() => {
                }
                );
                __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
                __Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.TagHelpers.LinkTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
                __Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper.Href = (string)__tagHelperAttribute_3.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_3);
#nullable restore
#line 13 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
__Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper.AppendVersion = true;

#line default
#line hidden
#nullable disable
                __tagHelperExecutionContext.AddTagHelperAttribute("asp-append-version", __Microsoft_AspNetCore_Mvc_TagHelpers_LinkTagHelper.AppendVersion, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n");
            }
            );
            __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_HeadTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper>();
            __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_HeadTagHelper);
            await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
            if (!__tagHelperExecutionContext.Output.IsContentModified)
            {
                await __tagHelperExecutionContext.SetOutputContentAsync();
            }
            Write(__tagHelperExecutionContext.Output);
            __tagHelperExecutionContext = __tagHelperScopeManager.End();
            WriteLiteral("\r\n");
            __tagHelperExecutionContext = __tagHelperScopeManager.Begin("body", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed515423", async() => {
                WriteLiteral("\r\n    <header>\r\n        <nav b-jhf4u2mpiu class=\"navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3\">\r\n            <div b-jhf4u2mpiu class=\"container-fluid\">\r\n                ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed515935", async() => {
                    WriteLiteral("SafeRoutingDemo");
                }
                );
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_4);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Area = (string)__tagHelperAttribute_5.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Controller = (string)__tagHelperAttribute_6.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Action = (string)__tagHelperAttribute_7.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_7);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral(@"
                <button b-jhf4u2mpiu class=""navbar-toggler"" type=""button"" data-bs-toggle=""collapse"" data-bs-target="".navbar-collapse"" aria-controls=""navbarSupportedContent""
                        aria-expanded=""false"" aria-label=""Toggle navigation"">
                    <span b-jhf4u2mpiu class=""navbar-toggler-icon""></span>
                </button>
                <div b-jhf4u2mpiu class=""navbar-collapse collapse d-sm-inline-flex justify-content-between"">
                    <ul b-jhf4u2mpiu class=""navbar-nav flex-grow-1"">
                        <li b-jhf4u2mpiu class=""nav-item"">
                            ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed518342", async() => {
                    WriteLiteral("Home");
                }
                );
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_8);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Area = (string)__tagHelperAttribute_5.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Controller = (string)__tagHelperAttribute_6.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Action = (string)__tagHelperAttribute_7.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_7);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n                        </li>\r\n                        <li b-jhf4u2mpiu class=\"nav-item\">\r\n                            ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed520218", async() => {
                    WriteLiteral("Privacy");
                }
                );
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_8);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Area = (string)__tagHelperAttribute_5.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Controller = (string)__tagHelperAttribute_6.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Action = (string)__tagHelperAttribute_9.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_9);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n                            ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed522000", async() => {
                    WriteLiteral("!New Privacy!");
                }
                );
                __SafeRouting_TagHelpers_RouteValuesTagHelper = CreateTagHelper<global::SafeRouting.TagHelpers.RouteValuesTagHelper>();
                __tagHelperExecutionContext.Add(__SafeRouting_TagHelpers_RouteValuesTagHelper);
#nullable restore
#line 31 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
__SafeRouting_TagHelpers_RouteValuesTagHelper.ForRoute = privacy;

#line default
#line hidden
#nullable disable
                __tagHelperExecutionContext.AddTagHelperAttribute("for-route", __SafeRouting_TagHelpers_RouteValuesTagHelper.ForRoute, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n                        </li>\r\n                    </ul>\r\n                </div>\r\n            </div>\r\n        </nav>\r\n    </header>\r\n    <div b-jhf4u2mpiu class=\"container\">\r\n        <main b-jhf4u2mpiu role=\"main\" class=\"pb-3\">\r\n            ");
#nullable restore
#line (40,14)-(40,26) 6 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
Write(RenderBody());

#line default
#line hidden
#nullable disable
                WriteLiteral("\r\n        </main>\r\n    </div>\r\n\r\n    <footer b-jhf4u2mpiu class=\"border-top footer text-muted\">\r\n        <div b-jhf4u2mpiu class=\"container\">\r\n            &copy; 2023 - SafeRoutingDemo - ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("a", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed524225", async() => {
                    WriteLiteral("Privacy");
                }
                );
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Area = (string)__tagHelperAttribute_5.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Controller = (string)__tagHelperAttribute_6.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
                __Microsoft_AspNetCore_Mvc_TagHelpers_AnchorTagHelper.Action = (string)__tagHelperAttribute_9.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_9);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n        </div>\r\n    </footer>\r\n    ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("script", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed525931", async() => {
                }
                );
                __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_10);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n    ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("script", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed527056", async() => {
                }
                );
                __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
                __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_11);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n    ");
                __tagHelperExecutionContext = __tagHelperScopeManager.Begin("script", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "72c7981441e7dd8348577278ecfae982d81850efd7ef5a304555b32696efeed528181", async() => {
                }
                );
                __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
                __Microsoft_AspNetCore_Mvc_TagHelpers_ScriptTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper>();
                __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_TagHelpers_ScriptTagHelper);
                __Microsoft_AspNetCore_Mvc_TagHelpers_ScriptTagHelper.Src = (string)__tagHelperAttribute_12.Value;
                __tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_12);
#nullable restore
#line 51 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
__Microsoft_AspNetCore_Mvc_TagHelpers_ScriptTagHelper.AppendVersion = true;

#line default
#line hidden
#nullable disable
                __tagHelperExecutionContext.AddTagHelperAttribute("asp-append-version", __Microsoft_AspNetCore_Mvc_TagHelpers_ScriptTagHelper.AppendVersion, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
                await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
                if (!__tagHelperExecutionContext.Output.IsContentModified)
                {
                    await __tagHelperExecutionContext.SetOutputContentAsync();
                }
                Write(__tagHelperExecutionContext.Output);
                __tagHelperExecutionContext = __tagHelperScopeManager.End();
                WriteLiteral("\r\n    ");
#nullable restore
#line (52,6)-(52,58) 6 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_Layout.cshtml"
Write(await RenderSectionAsync("Scripts", required: false));

#line default
#line hidden
#nullable disable
                WriteLiteral("\r\n");
            }
            );
            __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_BodyTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper>();
            __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_BodyTagHelper);
            await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
            if (!__tagHelperExecutionContext.Output.IsContentModified)
            {
                await __tagHelperExecutionContext.SetOutputContentAsync();
            }
            Write(__tagHelperExecutionContext.Output);
            __tagHelperExecutionContext = __tagHelperScopeManager.End();
            WriteLiteral("\r\n</html>\r\n");
        }
        #pragma warning restore 1998
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
        #nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\Shared\_ValidationScriptsPartial.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "9ef82fee87759dfecf2638af263085e669aa14a40c723d556d790d65a525ba11"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Shared__ValidationScriptsPartial), @"mvc.1.0.view", @"/Views/Shared/_ValidationScriptsPartial.cshtml")]
namespace AspNetCoreGeneratedDocument
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Mvc;
    using global::Microsoft.AspNetCore.Mvc.Rendering;
    using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo.Models;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/Shared/_ValidationScriptsPartial.cshtml")]
    [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
    #nullable restore
    internal sealed class Views_Shared__ValidationScriptsPartial : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    #nullable disable
    {
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_0 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("src", new global::Microsoft.AspNetCore.Html.HtmlString("~/lib/jquery-validation/dist/jquery.validate.min.js"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        private static readonly global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute __tagHelperAttribute_1 = new global::Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute("src", new global::Microsoft.AspNetCore.Html.HtmlString("~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"), global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
        #line hidden
        #pragma warning disable 0649
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
        #pragma warning restore 0649
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
        #pragma warning disable 0169
        private string __tagHelperStringValueBuffer;
        #pragma warning restore 0169
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
        private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
        {
            get
            {
                if (__backed__tagHelperScopeManager == null)
                {
                    __backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
                }
                return __backed__tagHelperScopeManager;
            }
        }
        private global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper;
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
            __tagHelperExecutionContext = __tagHelperScopeManager.Begin("script", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "9ef82fee87759dfecf2638af263085e669aa14a40c723d556d790d65a525ba114105", async() => {
            }
            );
            __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
            __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
            __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_0);
            await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
            if (!__tagHelperExecutionContext.Output.IsContentModified)
            {
                await __tagHelperExecutionContext.SetOutputContentAsync();
            }
            Write(__tagHelperExecutionContext.Output);
            __tagHelperExecutionContext = __tagHelperScopeManager.End();
            WriteLiteral("\r\n");
            __tagHelperExecutionContext = __tagHelperScopeManager.Begin("script", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "9ef82fee87759dfecf2638af263085e669aa14a40c723d556d790d65a525ba115168", async() => {
            }
            );
            __Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper = CreateTagHelper<global::Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper>();
            __tagHelperExecutionContext.Add(__Microsoft_AspNetCore_Mvc_Razor_TagHelpers_UrlResolutionTagHelper);
            __tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_1);
            await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
            if (!__tagHelperExecutionContext.Output.IsContentModified)
            {
                await __tagHelperExecutionContext.SetOutputContentAsync();
            }
            Write(__tagHelperExecutionContext.Output);
            __tagHelperExecutionContext = __tagHelperScopeManager.End();
            WriteLiteral("\r\n");
        }
        #pragma warning restore 1998
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
        #nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "b33e7bd52eada9ce3928211612ba84bf831cb9aab96479c704f9264424ab4158"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views__ViewImports), @"mvc.1.0.view", @"/Views/_ViewImports.cshtml")]
namespace AspNetCoreGeneratedDocument
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Mvc;
    using global::Microsoft.AspNetCore.Mvc.Rendering;
    using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo.Models;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/_ViewImports.cshtml")]
    [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
    #nullable restore
    internal sealed class Views__ViewImports : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    #nullable disable
    {
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
        }
        #pragma warning restore 1998
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
        #nullable disable
    }
}
#pragma warning restore 1591

#pragma checksum "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewStart.cshtml" "{8829d00f-11b8-4213-878b-770e8597ac16}" "47e02b4da20d198892b7b1b00b12944068797c438ef2e82d20ff70b4d56bad39"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views__ViewStart), @"mvc.1.0.view", @"/Views/_ViewStart.cshtml")]
namespace AspNetCoreGeneratedDocument
{
    #line hidden
    using global::System;
    using global::System.Collections.Generic;
    using global::System.Linq;
    using global::System.Threading.Tasks;
    using global::Microsoft.AspNetCore.Mvc;
    using global::Microsoft.AspNetCore.Mvc.Rendering;
    using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo;

#line default
#line hidden
#nullable disable
#nullable restore
#line 2 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewImports.cshtml"
using SafeRoutingDemo.Models;

#line default
#line hidden
#nullable disable
    [global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/_ViewStart.cshtml")]
    [global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
    #nullable restore
    internal sealed class Views__ViewStart : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
    #nullable disable
    {
        #pragma warning disable 1998
        public async override global::System.Threading.Tasks.Task ExecuteAsync()
        {
#nullable restore
#line 1 "C:\gth\RSCG_Examples\v2\rscg_examples\SafeRouting\src\SafeRouting\SafeRoutingDemo\Views\_ViewStart.cshtml"
  
    Layout = "_Layout";

#line default
#line hidden
#nullable disable
        }
        #pragma warning restore 1998
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
        #nullable disable
        #nullable restore
        [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
        #nullable disable
    }
}
#pragma warning restore 1591

// <auto-generated/>

#pragma warning disable
#nullable enable

namespace Routes
{
  namespace Controllers
  {
    /// <summary>
    /// Generates route values for <see cref="global::SafeRoutingDemo.Controllers.HomeController"/>.
    /// </summary>
    [global::System.CodeDom.Compiler.GeneratedCode("SafeRouting.Generator", "1.4.0.0")]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
    public static class Home
    {
      /// <summary>
      /// Generates route values for <see cref="global::SafeRoutingDemo.Controllers.HomeController.Index()"/>.
      /// </summary>
      public static Support.Controllers_Home.IndexRouteValues Index()
      {
        return new Support.Controllers_Home.IndexRouteValues(new global::Microsoft.AspNetCore.Routing.RouteValueDictionary()
        {
          ["area"] = ""
        });
      }

      /// <summary>
      /// Generates route values for <see cref="global::SafeRoutingDemo.Controllers.HomeController.Privacy()"/>.
      /// </summary>
      public static Support.Controllers_Home.PrivacyRouteValues Privacy()
      {
        return new Support.Controllers_Home.PrivacyRouteValues(new global::Microsoft.AspNetCore.Routing.RouteValueDictionary()
        {
          ["area"] = ""
        });
      }

      /// <summary>
      /// Generates route values for <see cref="global::SafeRoutingDemo.Controllers.HomeController.Error()"/>.
      /// </summary>
      public static Support.Controllers_Home.ErrorRouteValues Error()
      {
        return new Support.Controllers_Home.ErrorRouteValues(new global::Microsoft.AspNetCore.Routing.RouteValueDictionary()
        {
          ["area"] = ""
        });
      }
    }
  }

  namespace Support.Controllers_Home
  {
    /// <summary>
    /// Represents route values for routes to <see cref="global::SafeRoutingDemo.Controllers.HomeController.Index()"/>.
    /// </summary>
    [global::System.CodeDom.Compiler.GeneratedCode("SafeRouting.Generator", "1.4.0.0")]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
    public sealed class IndexRouteValues : global::SafeRouting.IControllerRouteValues
    {
      /// <summary>
      /// Initialises a new instance of the <see cref="IndexRouteValues"/> class.
      /// </summary>
      /// <param name="routeValues">The initial values for the route.</param>
      public IndexRouteValues(global::Microsoft.AspNetCore.Routing.RouteValueDictionary routeValues)
      {
        RouteValues = routeValues;
      }

      /// <summary>
      /// The name of the controller for the route.
      /// </summary>
      public string ControllerName => "Home";
      /// <summary>
      /// The name of the action for the route.
      /// </summary>
      public string ActionName => "Index";
      /// <summary>
      /// Values for the route.
      /// </summary>
      public global::Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { get; }
    }

    /// <summary>
    /// Represents route values for routes to <see cref="global::SafeRoutingDemo.Controllers.HomeController.Privacy()"/>.
    /// </summary>
    [global::System.CodeDom.Compiler.GeneratedCode("SafeRouting.Generator", "1.4.0.0")]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
    public sealed class PrivacyRouteValues : global::SafeRouting.IControllerRouteValues
    {
      /// <summary>
      /// Initialises a new instance of the <see cref="PrivacyRouteValues"/> class.
      /// </summary>
      /// <param name="routeValues">The initial values for the route.</param>
      public PrivacyRouteValues(global::Microsoft.AspNetCore.Routing.RouteValueDictionary routeValues)
      {
        RouteValues = routeValues;
      }

      /// <summary>
      /// The name of the controller for the route.
      /// </summary>
      public string ControllerName => "Home";
      /// <summary>
      /// The name of the action for the route.
      /// </summary>
      public string ActionName => "Privacy";
      /// <summary>
      /// Values for the route.
      /// </summary>
      public global::Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { get; }
    }

    /// <summary>
    /// Represents route values for routes to <see cref="global::SafeRoutingDemo.Controllers.HomeController.Error()"/>.
    /// </summary>
    [global::System.CodeDom.Compiler.GeneratedCode("SafeRouting.Generator", "1.4.0.0")]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
    public sealed class ErrorRouteValues : global::SafeRouting.IControllerRouteValues
    {
      /// <summary>
      /// Initialises a new instance of the <see cref="ErrorRouteValues"/> class.
      /// </summary>
      /// <param name="routeValues">The initial values for the route.</param>
      public ErrorRouteValues(global::Microsoft.AspNetCore.Routing.RouteValueDictionary routeValues)
      {
        RouteValues = routeValues;
      }

      /// <summary>
      /// The name of the controller for the route.
      /// </summary>
      public string ControllerName => "Home";
      /// <summary>
      /// The name of the action for the route.
      /// </summary>
      public string ActionName => "Error";
      /// <summary>
      /// Values for the route.
      /// </summary>
      public global::Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { get; }
    }
  }
}

// <auto-generated/>

global using static SafeRouting.Extensions.RouteValueExtensions;

Code and pdf at

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

RSCG – SourceGenerator.Helper.CopyCode

RSCG – SourceGenerator.Helper.CopyCode
 
 

name SourceGenerator.Helper.CopyCode
nuget https://www.nuget.org/packages/SourceGenerator.Helper.CopyCode/
link https://github.com/LokiMidgard/SourceGenerator.Helper.CopyCode
author Patrick Kranz

Transform Code to string

 

This is how you can use SourceGenerator.Helper.CopyCode .

The code that you start with is


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

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

  <ItemGroup>
    <PackageReference Include="SourceGenerator.Helper.CopyCode" Version="0.0.1">
      <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


Console.WriteLine(SourceGenerator.Helper.CopyCode.Copy.SourceGenerator_Helper_CopyCodeDemoNumberAttribute);
Console.WriteLine(SourceGenerator.Helper.CopyCode.Copy.SourceGenerator_Helper_CopyCodeDemoPerson);




namespace SourceGenerator_Helper_CopyCodeDemo;
[SourceGenerator.Helper.CopyCode.Copy]
[System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
internal sealed class NumberAttribute : Attribute
{
    public int ID;
}

[SourceGenerator.Helper.CopyCode.Copy]
internal class Person
{
    public int Id { get; set; }
}


 

The code that is generated is

// <auto-generated/>
#nullable enable

namespace SourceGenerator.Helper.CopyCode
{
	[global::System.CodeDom.Compiler.GeneratedCodeAttribute("SourceGenerator.Helper.CopyCode", "0.0.1.0")]
	[global::System.AttributeUsage(global::System.AttributeTargets.Enum | global::System.AttributeTargets.Class | global::System.AttributeTargets.Struct | global::System.AttributeTargets.Interface, AllowMultiple = false)]
	internal sealed class CopyAttribute : global::System.Attribute
	{
	}
}

// <auto-generated/>
#nullable enable
namespace SourceGenerator.Helper.CopyCode;
internal  static partial class Copy {
    public const string SourceGenerator_Helper_CopyCodeDemoNumberAttribute = """
        // <auto-generated/>
        #nullable enable
        
        namespace SourceGenerator_Helper_CopyCodeDemo;
        [System.AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
        internal sealed class NumberAttribute : Attribute
        {
            public int ID;
        }
        """;
}

// <auto-generated/>
#nullable enable
namespace SourceGenerator.Helper.CopyCode;
internal  static partial class Copy {
    public const string SourceGenerator_Helper_CopyCodeDemoPerson = """
        // <auto-generated/>
        #nullable enable
        
        namespace SourceGenerator_Helper_CopyCodeDemo;
        internal class Person
        {
            public int Id { get; set; }
        }
        """;
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/SourceGenerator.Helper.CopyCode

RSCG – NetEscapades.EnumGenerators

RSCG – NetEscapades.EnumGenerators
 
 

name NetEscapades.EnumGenerators
nuget https://www.nuget.org/packages/NetEscapades.EnumGenerators/
link https://andrewlock.net/netescapades-enumgenerators-a-source-generator-for-enum-performance/
author Andrew Lock

Running fast tostring and other features for enum

 

This is how you can use NetEscapades.EnumGenerators .

The code that you start with is


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

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

  <ItemGroup>
    <PackageReference Include="NetEscapades.EnumGenerators" Version="1.0.0-beta08" 
					  OutputItemType="Analyzer" ReferenceOutputAssembly="false"
					  PrivateAssets="all" ExcludeAssets="comile;runtime"
					  />
  </ItemGroup>
 <PropertyGroup>
        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
        <CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
    </PropertyGroup>
  
</Project>


The code that you will use is



var value = InstallType.ShowGUI;
Console.WriteLine($"the enum string is {value.ToStringFast()}");
Console.WriteLine($"{InstallType.None.ToStringFast()}");


var flags = AddToCoffee.Milk | AddToCoffee.Sugar;

Console.WriteLine(flags.ToStringFast());
Console.WriteLine($"HasFlag(Milk), {flags.HasFlagFast(AddToCoffee.Milk)}");
Console.WriteLine($"HasFlag(Biscuit), {flags.HasFlagFast(AddToCoffee.Biscuit)}");
//check also
//InstallTypeExtensions.GetNames
//AddToCoffeeExtensions.GetNames


using NetEscapades.EnumGenerators;
using System.ComponentModel.DataAnnotations;
using System.Xml.Linq;

[EnumExtensions]
internal enum InstallType
{
    [Display(Name = $"Please use one of the flags of {nameof(InstallType)}")]
    None= 0,
    
    ShowGUI,
    ShowNoGui,
}



using NetEscapades.EnumGenerators;

[EnumExtensions]
[Flags]
internal enum AddToCoffee
{
    None= 0,
    Milk=1,
    Sugar=2,
    Biscuit=4
}

 

The code that is generated is

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

#nullable enable
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
using System;
#endif

    /// <summary>
    /// Extension methods for <see cref="global::AddToCoffee" />
    /// </summary>
    internal static partial class AddToCoffeeExtensions
    {
        /// <summary>
        /// The number of members in the enum.
        /// This is a non-distinct count of defined names.
        /// </summary>
        public const int Length = 4;

        /// <summary>
        /// Returns the string representation of the <see cref="global::AddToCoffee"/> value.
        /// If the attribute is decorated with a <c>[Display]</c> attribute, then
        /// uses the provided value. Otherwise uses the name of the member, equivalent to
        /// calling <c>ToString()</c> on <paramref name="value"/>.
        /// </summary>
        /// <param name="value">The value to retrieve the string value for</param>
        /// <returns>The string representation of the value</returns>
        public static string ToStringFast(this global::AddToCoffee value)
            => value switch
            {
                global::AddToCoffee.None => nameof(global::AddToCoffee.None),
                global::AddToCoffee.Milk => nameof(global::AddToCoffee.Milk),
                global::AddToCoffee.Sugar => nameof(global::AddToCoffee.Sugar),
                global::AddToCoffee.Biscuit => nameof(global::AddToCoffee.Biscuit),
                _ => value.ToString(),
            };

        /// <summary>
        /// Determines whether one or more bit fields are set in the current instance.
        /// Equivalent to calling <see cref="global::System.Enum.HasFlag" /> on <paramref name="value"/>.
        /// </summary>
        /// <param name="value">The value of the instance to investigate</param>
        /// <param name="flag">The flag to check for</param>
        /// <returns><c>true</c> if the fields set in the flag are also set in the current instance; otherwise <c>false</c>.</returns>
        /// <remarks>If the underlying value of <paramref name="flag"/> is zero, the method returns true.
        /// This is consistent with the behaviour of <see cref="global::System.Enum.HasFlag" /></remarks>
        public static bool HasFlagFast(this global::AddToCoffee value, global::AddToCoffee flag)
            => flag == 0 ? true : (value & flag) == flag;

        /// <summary>
        /// Returns a boolean telling whether the given enum value exists in the enumeration.
        /// </summary>
        /// <param name="value">The value to check if it's defined</param>
        /// <returns><c>true</c> if the value exists in the enumeration, <c>false</c> otherwise</returns>
       public static bool IsDefined(global::AddToCoffee value)
            => value switch
            {
                global::AddToCoffee.None => true,
                global::AddToCoffee.Milk => true,
                global::AddToCoffee.Sugar => true,
                global::AddToCoffee.Biscuit => true,
                _ => false,
            };

        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration.
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
        public static bool IsDefined(string name) => IsDefined(name, allowMatchingMetadataAttribute: false);

        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration,
        /// or if a member decorated with a <c>[Display]</c> attribute
        /// with the required name exists.
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
        /// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
        public static bool IsDefined(string name, bool allowMatchingMetadataAttribute)
        {
            return name switch
            {
                nameof(global::AddToCoffee.None) => true,
                nameof(global::AddToCoffee.Milk) => true,
                nameof(global::AddToCoffee.Sugar) => true,
                nameof(global::AddToCoffee.Biscuit) => true,
                _ => false,
            };
        }

#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
        public static bool IsDefined(in ReadOnlySpan<char> name) => IsDefined(name, allowMatchingMetadataAttribute: false);

        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration,
        /// or optionally if a member decorated with a <c>[Display]</c> attribute
        /// with the required name exists.
        /// Slower then the <see cref="IsDefined(string, bool)" /> overload, but doesn't allocate memory./>
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
        /// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
        public static bool IsDefined(in ReadOnlySpan<char> name, bool allowMatchingMetadataAttribute)
        {
            return name switch
            {
                ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.None).AsSpan(), global::System.StringComparison.Ordinal) => true,
                ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Milk).AsSpan(), global::System.StringComparison.Ordinal) => true,
                ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Sugar).AsSpan(), global::System.StringComparison.Ordinal) => true,
                ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Biscuit).AsSpan(), global::System.StringComparison.Ordinal) => true,
                _ => false,
            };
        }
#endif

        /// <summary>
        /// Converts the string representation of the name or numeric value of
        /// an <see cref="global::AddToCoffee" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The case-sensitive string representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::AddToCoffee" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            string? name, 
            out global::AddToCoffee value)
            => TryParse(name, out value, false, false);

        /// <summary>
        /// Converts the string representation of the name or numeric value of
        /// an <see cref="global::AddToCoffee" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::AddToCoffee" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            string? name, 
            out global::AddToCoffee value,
            bool ignoreCase) 
            => TryParse(name, out value, ignoreCase, false);

        /// <summary>
        /// Converts the string representation of the name or numeric value of
        /// an <see cref="global::AddToCoffee" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::AddToCoffee" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
        /// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            string? name, 
            out global::AddToCoffee value, 
            bool ignoreCase, 
            bool allowMatchingMetadataAttribute)
        {
            if (ignoreCase)
            {
                switch (name)
                {
                    case string s when s.Equals(nameof(global::AddToCoffee.None), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::AddToCoffee.None;
                        return true;
                    case string s when s.Equals(nameof(global::AddToCoffee.Milk), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::AddToCoffee.Milk;
                        return true;
                    case string s when s.Equals(nameof(global::AddToCoffee.Sugar), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::AddToCoffee.Sugar;
                        return true;
                    case string s when s.Equals(nameof(global::AddToCoffee.Biscuit), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::AddToCoffee.Biscuit;
                        return true;
                    case string s when int.TryParse(name, out var val):
                        value = (global::AddToCoffee)val;
                        return true;
                    default:
                        value = default;
                        return false;
                }
            }
            else
            {
                switch (name)
                {
                    case nameof(global::AddToCoffee.None):
                        value = global::AddToCoffee.None;
                        return true;
                    case nameof(global::AddToCoffee.Milk):
                        value = global::AddToCoffee.Milk;
                        return true;
                    case nameof(global::AddToCoffee.Sugar):
                        value = global::AddToCoffee.Sugar;
                        return true;
                    case nameof(global::AddToCoffee.Biscuit):
                        value = global::AddToCoffee.Biscuit;
                        return true;
                    case string s when int.TryParse(name, out var val):
                        value = (global::AddToCoffee)val;
                        return true;
                    default:
                        value = default;
                        return false;
                }
            }
        }

#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
        /// <summary>
        /// Converts the span representation of the name or numeric value of
        /// an <see cref="global::AddToCoffee" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::AddToCoffee" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            in ReadOnlySpan<char> name, 
            out global::AddToCoffee value)
            => TryParse(name, out value, false, false);

        /// <summary>
        /// Converts the span representation of the name or numeric value of
        /// an <see cref="global::AddToCoffee" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::AddToCoffee" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            in ReadOnlySpan<char> name, 
            out global::AddToCoffee value,
            bool ignoreCase) 
            => TryParse(name, out value, ignoreCase, false);

        /// <summary>
        /// Converts the span representation of the name or numeric value of
        /// an <see cref="global::AddToCoffee" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
        /// <param name="result">When this method returns, contains an object of type 
        /// <see cref="global::AddToCoffee" /> whose
        /// value is represented by <paramref name="result"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
        /// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            in ReadOnlySpan<char> name, 
            out global::AddToCoffee result, 
            bool ignoreCase,             
            bool allowMatchingMetadataAttribute)
        {
            if (ignoreCase)
            {
                switch (name)
                {
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.None).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                        result = global::AddToCoffee.None;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Milk).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                        result = global::AddToCoffee.Milk;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Sugar).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                        result = global::AddToCoffee.Sugar;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Biscuit).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                        result = global::AddToCoffee.Biscuit;
                        return true;
                    case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
                        result = (global::AddToCoffee)numericResult;
                        return true;
                    default:
                        result = default;
                        return false;
                }
            }
            else
            {
                switch (name)
                {
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.None).AsSpan(), global::System.StringComparison.Ordinal):
                        result = global::AddToCoffee.None;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Milk).AsSpan(), global::System.StringComparison.Ordinal):
                        result = global::AddToCoffee.Milk;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Sugar).AsSpan(), global::System.StringComparison.Ordinal):
                        result = global::AddToCoffee.Sugar;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Biscuit).AsSpan(), global::System.StringComparison.Ordinal):
                        result = global::AddToCoffee.Biscuit;
                        return true;
                    case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
                        result = (global::AddToCoffee)numericResult;
                        return true;
                    default:
                        result = default;
                        return false;
                }
            }
        }
#endif

        /// <summary>
        /// Retrieves an array of the values of the members defined in
        /// <see cref="global::AddToCoffee" />.
        /// Note that this returns a new array with every invocation, so
        /// should be cached if appropriate.
        /// </summary>
        /// <returns>An array of the values defined in <see cref="global::AddToCoffee" /></returns>
        public static global::AddToCoffee[] GetValues()
        {
            return new[]
            {
                global::AddToCoffee.None,
                global::AddToCoffee.Milk,
                global::AddToCoffee.Sugar,
                global::AddToCoffee.Biscuit,
            };
        }

        /// <summary>
        /// Retrieves an array of the names of the members defined in
        /// <see cref="global::AddToCoffee" />.
        /// Note that this returns a new array with every invocation, so
        /// should be cached if appropriate.
        /// </summary>
        /// <returns>An array of the names of the members defined in <see cref="global::AddToCoffee" /></returns>
        public static string[] GetNames()
        {
            return new[]
            {
                nameof(global::AddToCoffee.None),
                nameof(global::AddToCoffee.Milk),
                nameof(global::AddToCoffee.Sugar),
                nameof(global::AddToCoffee.Biscuit),
            };
        }
    }
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the NetEscapades.EnumGenerators source generator
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

#if NETESCAPADES_ENUMGENERATORS_EMBED_ATTRIBUTES
namespace NetEscapades.EnumGenerators
{
    /// <summary>
    /// Add to enums to indicate that extension methods should be generated for the type
    /// </summary>
    [global::System.AttributeUsage(global::System.AttributeTargets.Enum)]
    [global::System.Diagnostics.Conditional("NETESCAPADES_ENUMGENERATORS_USAGES")]
#if NET5_0_OR_GREATER
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Generated by the NetEscapades.EnumGenerators source generator.")]
#else
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
    public class EnumExtensionsAttribute : global::System.Attribute
    {
        /// <summary>
        /// The namespace to generate the extension class.
        /// If not provided the namespace of the enum will be used
        /// </summary>
        public string? ExtensionClassNamespace { get; set; }

        /// <summary>
        /// The name to use for the extension class.
        /// If not provided, the enum name with "Extensions" will be used.
        /// For example for an Enum called StatusCodes, the default name
        /// will be StatusCodesExtensions
        /// </summary>
        public string? ExtensionClassName { get; set; }
    }
}
#endif

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

#nullable enable
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
using System;
#endif

    /// <summary>
    /// Extension methods for <see cref="global::InstallType" />
    /// </summary>
    internal static partial class InstallTypeExtensions
    {
        /// <summary>
        /// The number of members in the enum.
        /// This is a non-distinct count of defined names.
        /// </summary>
        public const int Length = 3;

        /// <summary>
        /// Returns the string representation of the <see cref="global::InstallType"/> value.
        /// If the attribute is decorated with a <c>[Display]</c> attribute, then
        /// uses the provided value. Otherwise uses the name of the member, equivalent to
        /// calling <c>ToString()</c> on <paramref name="value"/>.
        /// </summary>
        /// <param name="value">The value to retrieve the string value for</param>
        /// <returns>The string representation of the value</returns>
        public static string ToStringFast(this global::InstallType value)
            => value switch
            {
                global::InstallType.None => "Please use one of the flags of InstallType",
                global::InstallType.ShowGUI => nameof(global::InstallType.ShowGUI),
                global::InstallType.ShowNoGui => nameof(global::InstallType.ShowNoGui),
                _ => value.ToString(),
            };

        /// <summary>
        /// Returns a boolean telling whether the given enum value exists in the enumeration.
        /// </summary>
        /// <param name="value">The value to check if it's defined</param>
        /// <returns><c>true</c> if the value exists in the enumeration, <c>false</c> otherwise</returns>
       public static bool IsDefined(global::InstallType value)
            => value switch
            {
                global::InstallType.None => true,
                global::InstallType.ShowGUI => true,
                global::InstallType.ShowNoGui => true,
                _ => false,
            };

        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration.
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
        public static bool IsDefined(string name) => IsDefined(name, allowMatchingMetadataAttribute: false);

        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration,
        /// or if a member decorated with a <c>[Display]</c> attribute
        /// with the required name exists.
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
        /// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
        public static bool IsDefined(string name, bool allowMatchingMetadataAttribute)
        {
            var isDefinedInDisplayAttribute = false;
            if (allowMatchingMetadataAttribute)
            {
                isDefinedInDisplayAttribute = name switch
                {
                    "Please use one of the flags of InstallType" => true,
                    _ => false,
                };
            }

            if (isDefinedInDisplayAttribute)
            {
                return true;
            }

            
            return name switch
            {
                nameof(global::InstallType.None) => true,
                nameof(global::InstallType.ShowGUI) => true,
                nameof(global::InstallType.ShowNoGui) => true,
                _ => false,
            };
        }

#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
        public static bool IsDefined(in ReadOnlySpan<char> name) => IsDefined(name, allowMatchingMetadataAttribute: false);

        /// <summary>
        /// Returns a boolean telling whether an enum with the given name exists in the enumeration,
        /// or optionally if a member decorated with a <c>[Display]</c> attribute
        /// with the required name exists.
        /// Slower then the <see cref="IsDefined(string, bool)" /> overload, but doesn't allocate memory./>
        /// </summary>
        /// <param name="name">The name to check if it's defined</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
        /// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
        /// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
        public static bool IsDefined(in ReadOnlySpan<char> name, bool allowMatchingMetadataAttribute)
        {
            var isDefinedInDisplayAttribute = false;
            if (allowMatchingMetadataAttribute)
            {
                isDefinedInDisplayAttribute = name switch
                {
                    ReadOnlySpan<char> current when current.Equals("Please use one of the flags of InstallType".AsSpan(), global::System.StringComparison.Ordinal) => true,
                    _ => false,
                };
            }

            if (isDefinedInDisplayAttribute)
            {
                return true;
            }

            return name switch
            {
                ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.None).AsSpan(), global::System.StringComparison.Ordinal) => true,
                ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowGUI).AsSpan(), global::System.StringComparison.Ordinal) => true,
                ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowNoGui).AsSpan(), global::System.StringComparison.Ordinal) => true,
                _ => false,
            };
        }
#endif

        /// <summary>
        /// Converts the string representation of the name or numeric value of
        /// an <see cref="global::InstallType" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The case-sensitive string representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::InstallType" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            string? name, 
            out global::InstallType value)
            => TryParse(name, out value, false, false);

        /// <summary>
        /// Converts the string representation of the name or numeric value of
        /// an <see cref="global::InstallType" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::InstallType" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            string? name, 
            out global::InstallType value,
            bool ignoreCase) 
            => TryParse(name, out value, ignoreCase, false);

        /// <summary>
        /// Converts the string representation of the name or numeric value of
        /// an <see cref="global::InstallType" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::InstallType" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
        /// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            string? name, 
            out global::InstallType value, 
            bool ignoreCase, 
            bool allowMatchingMetadataAttribute)
        {
            if (allowMatchingMetadataAttribute)
            {
                if (ignoreCase)
                {
                    switch (name)
                    {
                        case string s when s.Equals("Please use one of the flags of InstallType", global::System.StringComparison.OrdinalIgnoreCase):
                            value = global::InstallType.None;
                            return true;
                        default:
                            break;
                    };
                }
                else
                {
                    switch (name)
                    {
                        case "Please use one of the flags of InstallType":
                            value = global::InstallType.None;
                            return true;
                        default:
                            break;
                    };
                }
            }

            if (ignoreCase)
            {
                switch (name)
                {
                    case string s when s.Equals(nameof(global::InstallType.None), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::InstallType.None;
                        return true;
                    case string s when s.Equals(nameof(global::InstallType.ShowGUI), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::InstallType.ShowGUI;
                        return true;
                    case string s when s.Equals(nameof(global::InstallType.ShowNoGui), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::InstallType.ShowNoGui;
                        return true;
                    case string s when int.TryParse(name, out var val):
                        value = (global::InstallType)val;
                        return true;
                    default:
                        value = default;
                        return false;
                }
            }
            else
            {
                switch (name)
                {
                    case nameof(global::InstallType.None):
                        value = global::InstallType.None;
                        return true;
                    case nameof(global::InstallType.ShowGUI):
                        value = global::InstallType.ShowGUI;
                        return true;
                    case nameof(global::InstallType.ShowNoGui):
                        value = global::InstallType.ShowNoGui;
                        return true;
                    case string s when int.TryParse(name, out var val):
                        value = (global::InstallType)val;
                        return true;
                    default:
                        value = default;
                        return false;
                }
            }
        }

#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
        /// <summary>
        /// Converts the span representation of the name or numeric value of
        /// an <see cref="global::InstallType" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::InstallType" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            in ReadOnlySpan<char> name, 
            out global::InstallType value)
            => TryParse(name, out value, false, false);

        /// <summary>
        /// Converts the span representation of the name or numeric value of
        /// an <see cref="global::InstallType" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
        /// <param name="value">When this method returns, contains an object of type 
        /// <see cref="global::InstallType" /> whose
        /// value is represented by <paramref name="value"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            in ReadOnlySpan<char> name, 
            out global::InstallType value,
            bool ignoreCase) 
            => TryParse(name, out value, ignoreCase, false);

        /// <summary>
        /// Converts the span representation of the name or numeric value of
        /// an <see cref="global::InstallType" /> to the equivalent instance.
        /// The return value indicates whether the conversion succeeded.
        /// </summary>
        /// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
        /// <param name="result">When this method returns, contains an object of type 
        /// <see cref="global::InstallType" /> whose
        /// value is represented by <paramref name="result"/> if the parse operation succeeds.
        /// If the parse operation fails, contains the default value of the underlying type
        /// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
        /// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
        /// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
        /// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
        /// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            in ReadOnlySpan<char> name, 
            out global::InstallType result, 
            bool ignoreCase,             
            bool allowMatchingMetadataAttribute)
        {
            if (allowMatchingMetadataAttribute)
            {
                if (ignoreCase)
                {
                    switch (name)
                    {
                        case ReadOnlySpan<char> current when current.Equals("Please use one of the flags of InstallType".AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                            result = global::InstallType.None;
                            return true;
                        default:
                            break;
                    };
                }
                else
                {
                    switch (name)
                    {
                        case ReadOnlySpan<char> current when current.Equals("Please use one of the flags of InstallType".AsSpan(), global::System.StringComparison.Ordinal):
                            result = global::InstallType.None;
                            return true;
                        default:
                            break;
                    };
                }
            }

            if (ignoreCase)
            {
                switch (name)
                {
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.None).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                        result = global::InstallType.None;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowGUI).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                        result = global::InstallType.ShowGUI;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowNoGui).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
                        result = global::InstallType.ShowNoGui;
                        return true;
                    case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
                        result = (global::InstallType)numericResult;
                        return true;
                    default:
                        result = default;
                        return false;
                }
            }
            else
            {
                switch (name)
                {
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.None).AsSpan(), global::System.StringComparison.Ordinal):
                        result = global::InstallType.None;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowGUI).AsSpan(), global::System.StringComparison.Ordinal):
                        result = global::InstallType.ShowGUI;
                        return true;
                    case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowNoGui).AsSpan(), global::System.StringComparison.Ordinal):
                        result = global::InstallType.ShowNoGui;
                        return true;
                    case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
                        result = (global::InstallType)numericResult;
                        return true;
                    default:
                        result = default;
                        return false;
                }
            }
        }
#endif

        /// <summary>
        /// Retrieves an array of the values of the members defined in
        /// <see cref="global::InstallType" />.
        /// Note that this returns a new array with every invocation, so
        /// should be cached if appropriate.
        /// </summary>
        /// <returns>An array of the values defined in <see cref="global::InstallType" /></returns>
        public static global::InstallType[] GetValues()
        {
            return new[]
            {
                global::InstallType.None,
                global::InstallType.ShowGUI,
                global::InstallType.ShowNoGui,
            };
        }

        /// <summary>
        /// Retrieves an array of the names of the members defined in
        /// <see cref="global::InstallType" />.
        /// Note that this returns a new array with every invocation, so
        /// should be cached if appropriate.
        /// </summary>
        /// <returns>An array of the names of the members defined in <see cref="global::InstallType" /></returns>
        public static string[] GetNames()
        {
            return new[]
            {
                nameof(global::InstallType.None),
                nameof(global::InstallType.ShowGUI),
                nameof(global::InstallType.ShowNoGui),
            };
        }
    }

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/NetEscapades.EnumGenerators

NetCoreUsefullEndpoints–part 6–passing to .NET 7

So  .NET 7 has appeared and I decided to pass NetCoreUsefullEndpoints to .NET 7 .

Also, for RateLimiter , I have considered that is good to know if the request is local or remote … so I decided to add connection ( remote IP, local IP, and more details) to the nuget package.

So I have created for .NET 6 this :

So , first things first : modify the version from  6.2022.1203.1551 to  7.2022.1203.1551 ( my versioning scheme is .NETCore version compliant of the package.year.MMdd.HHmm  – pretty stable and easy to decide what package you should add)

Then I want to profit to show in swagger the return type with TypedResults – so , as an example , I have modified from

route.MapGet(“api/usefull/httpContext/Connection”, (HttpContext httpContext) =>
{
var con = httpContext.Connection;
if (con == null)
{
     return Results.NoContent();
}
var conSerialize = new
{
     LocalIpAddress = con.LocalIpAddress?.ToString(),
     RemoteIpAddress = con.RemoteIpAddress?.ToString(),
     con.RemotePort,
     con.LocalPort,
     con.ClientCertificate,
     con.Id
};
return Results.Ok(conSerialize);

})

to

route.MapGet(“api/usefull/httpContext/Connection”,

Results<NoContent, Ok<object>>
(HttpContext httpContext) =>
{
var con = httpContext.Connection;
if (con == null)
{
     return TypedResults.NoContent();
}
var conSerialize = new
{
     LocalIpAddress = con.LocalIpAddress?.ToString(),
     RemoteIpAddress = con.RemoteIpAddress?.ToString(),
     con.RemotePort,
     con.LocalPort,
     con.ClientCertificate,
     con.Id
};
return TypedResults.Ok((object)conSerialize);
})

As you see , a pretty easy modification – indicating the INesteHttpResult Results<NoContent, Ok<object>>  ( so the swagger understand the 2 different return types )  and returning TypedResults instead of Results

Also the github ci must add the .NET Core and Azure App Service should be going to .NET 7 STS

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.