RSCG – Dusharp

RSCG – Dusharp
 
 

name Dusharp
nuget https://www.nuget.org/packages/Dusharp/
link https://github.com/kolebynov/Dusharp
author Vitali

Generate tagged union

 

This is how you can use Dusharp .

The code that you start with is


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

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

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

	<ItemGroup>
	  <PackageReference Include="Dusharp" Version="0.4.0">
	    <PrivateAssets>all</PrivateAssets>
	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
	  </PackageReference>
	</ItemGroup>

	

</Project>


The code that you will use is


using UnionTypesDemo;

Console.WriteLine("Save or not");
var data = SaveToDatabase.Save(0);
data.Match(
    ok => Console.WriteLine(ok),
    ()=> Console.WriteLine("Not found")
);

data = SaveToDatabase.Save(1);
data.Match(
    ok => Console.WriteLine(ok),
    () => Console.WriteLine("Not found")
);



using Dusharp;
namespace UnionTypesDemo;


[Union]
public partial class ResultSave
{
    [UnionCase]
    public static partial ResultSave Ok(int i);
    [UnionCase]
    public static partial ResultSave NotFound();
    
}




namespace UnionTypesDemo;

public class SaveToDatabase
{
    public static ResultSave Save(int i)
    {

        if (i == 0)
        {
            return ResultSave.NotFound();
        }
        return ResultSave.Ok(i); ;
    }
}




 

The code that is generated is

// <auto-generated> This file has been auto generated. </auto-generated>
#nullable enable
using System;
using System.Runtime.CompilerServices;

namespace Dusharp
{
	public static class ExceptionUtils
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void ThrowIfNull<T>(this T value, string paramName)
			where T : class
		{
			if (value == null)
			{
				ThrowArgumentNull(paramName);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void ThrowUnionInInvalidState() =>
			throw new InvalidOperationException("Union in invalid state.");

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void ThrowArgumentNull(string paramName) => throw new ArgumentNullException(paramName);
	}
}
// <auto-generated> This file has been auto generated. </auto-generated>
#nullable enable
using System;

namespace Dusharp
{
	[AttributeUsage(AttributeTargets.Class)]
	public sealed class UnionAttribute : Attribute
	{
	}
}
// <auto-generated> This file has been auto generated. </auto-generated>
#nullable enable
using System;

namespace Dusharp
{
	[AttributeUsage(AttributeTargets.Method)]
	public sealed class UnionCaseAttribute : Attribute
	{
	}
}
// <auto-generated> This file has been auto generated. </auto-generated>
#nullable enable
namespace UnionTypesDemo
{
	[System.Diagnostics.CodeAnalysis.SuppressMessage("", "CA1000", Justification = "For generic unions.")]
	abstract partial class ResultSave : System.IEquatable<ResultSave>
	{
		private ResultSave() {}

		public void Match(System.Action<int> okCase, System.Action notFoundCase)
		{
			Dusharp.ExceptionUtils.ThrowIfNull(okCase, "okCase");
			Dusharp.ExceptionUtils.ThrowIfNull(notFoundCase, "notFoundCase");

			{
				var unionCase = this as OkCase;
				if (!object.ReferenceEquals(unionCase, null)) { okCase(unionCase.i); return; }
			}

			{
				var unionCase = this as NotFoundCase;
				if (!object.ReferenceEquals(unionCase, null)) { notFoundCase(); return; }
			}

			Dusharp.ExceptionUtils.ThrowUnionInInvalidState();
		}

		public TRet Match<TRet>(System.Func<int, TRet> okCase, System.Func<TRet> notFoundCase)
		{
			Dusharp.ExceptionUtils.ThrowIfNull(okCase, "okCase");
			Dusharp.ExceptionUtils.ThrowIfNull(notFoundCase, "notFoundCase");

			{
				var unionCase = this as OkCase;
				if (!object.ReferenceEquals(unionCase, null)) { return okCase(unionCase.i); }
			}

			{
				var unionCase = this as NotFoundCase;
				if (!object.ReferenceEquals(unionCase, null)) { return notFoundCase(); }
			}

			Dusharp.ExceptionUtils.ThrowUnionInInvalidState();
			return default!;
		}

		public void Match<TState>(TState state, System.Action<TState, int> okCase, System.Action<TState> notFoundCase)
		{
			Dusharp.ExceptionUtils.ThrowIfNull(okCase, "okCase");
			Dusharp.ExceptionUtils.ThrowIfNull(notFoundCase, "notFoundCase");

			{
				var unionCase = this as OkCase;
				if (!object.ReferenceEquals(unionCase, null)) { okCase(state, unionCase.i); return; }
			}

			{
				var unionCase = this as NotFoundCase;
				if (!object.ReferenceEquals(unionCase, null)) { notFoundCase(state); return; }
			}

			Dusharp.ExceptionUtils.ThrowUnionInInvalidState();
		}

		public TRet Match<TState, TRet>(TState state, System.Func<TState, int, TRet> okCase, System.Func<TState, TRet> notFoundCase)
		{
			Dusharp.ExceptionUtils.ThrowIfNull(okCase, "okCase");
			Dusharp.ExceptionUtils.ThrowIfNull(notFoundCase, "notFoundCase");

			{
				var unionCase = this as OkCase;
				if (!object.ReferenceEquals(unionCase, null)) { return okCase(state, unionCase.i); }
			}

			{
				var unionCase = this as NotFoundCase;
				if (!object.ReferenceEquals(unionCase, null)) { return notFoundCase(state); }
			}

			Dusharp.ExceptionUtils.ThrowUnionInInvalidState();
			return default!;
		}

		public virtual bool Equals(ResultSave? other) { return object.ReferenceEquals(this, other); }
		public override bool Equals(object? other) { return object.ReferenceEquals(this, other); }
		public override int GetHashCode() { return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(this); }
		public static bool operator ==(ResultSave? left, ResultSave? right)
		{
			return !object.ReferenceEquals(left, null) ? left.Equals(right) : object.ReferenceEquals(left, right);
		}

		public static bool operator !=(ResultSave? left, ResultSave? right)
		{
			return !object.ReferenceEquals(left, null) ? !left.Equals(right) : !object.ReferenceEquals(left, right);
		}

		private sealed class OkCase : ResultSave
		{
			public readonly int i;
			public OkCase(int i)
			{
				this.i = i;
			}

			public override string ToString()
			{
				return $"Ok {{ i = {i} }}";
			}

			public override bool Equals(ResultSave? other)
			{
				if (object.ReferenceEquals(this, other)) return true;
				var otherCasted = other as OkCase;
				if (object.ReferenceEquals(otherCasted, null)) return false;
				return StructuralEquals(otherCasted);
			}

			public override bool Equals(object? other)
			{
				if (object.ReferenceEquals(this, other)) return true;
				var otherCasted = other as OkCase;
				if (object.ReferenceEquals(otherCasted, null)) return false;
				return StructuralEquals(otherCasted);
			}

			public override int GetHashCode()
			{
				unchecked { return System.Collections.Generic.EqualityComparer<int>.Default.GetHashCode(i!) * -1521134295 + "Ok".GetHashCode(); }
			}

			private bool StructuralEquals(OkCase other)
			{
				return System.Collections.Generic.EqualityComparer<int>.Default.Equals(i, other.i);
			}
		}

		public static partial ResultSave Ok(int i)
		{
			return new OkCase(i);
		}

		private sealed class NotFoundCase : ResultSave
		{
			public static readonly NotFoundCase Instance = new NotFoundCase();
			public NotFoundCase()
			{
			}

			public override string ToString()
			{
				return "NotFound";
			}
		}

		public static partial ResultSave NotFound()
		{
			return NotFoundCase.Instance;
		}
	}
}

// <auto-generated/>

#nullable enable

using Sera.TaggedUnion;

namespace UnionTypesDemo {

public partial struct ResultSave
    : global::Sera.TaggedUnion.ITaggedUnion
    , global::System.IEquatable<ResultSave>
    , global::System.IComparable<ResultSave>
#if NET7_0_OR_GREATER
    , global::System.Numerics.IEqualityOperators<ResultSave, ResultSave, bool>
    , global::System.Numerics.IComparisonOperators<ResultSave, ResultSave, bool>
#endif
{
    private __impl_ _impl;
    private ResultSave(__impl_ _impl) { this._impl = _impl; }

    public readonly Tags Tag
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        get => this._impl._tag;
    }

    public enum Tags : byte
    {
        Ok = 1,
        NotFound = 2,
    }

    [global::System.Runtime.CompilerServices.CompilerGenerated]
    private struct __impl_
    {
        public __unmanaged_ _unmanaged_;
        public readonly Tags _tag;

        [global::System.Runtime.CompilerServices.CompilerGenerated]
        [global::System.Runtime.InteropServices.StructLayout(global::System.Runtime.InteropServices.LayoutKind.Explicit)]
        internal struct __unmanaged_
        {
            [global::System.Runtime.InteropServices.FieldOffset(0)]
            public int _0;
        }

        public __impl_(Tags _tag)
        {
            global::System.Runtime.CompilerServices.Unsafe.SkipInit(out this._unmanaged_);
            this._tag = _tag;
        }
    }

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static ResultSave MakeOk(int value)
    {
        var _impl = new __impl_(Tags.Ok);
        _impl._unmanaged_._0 = value;
        return new ResultSave(_impl);
    }
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static ResultSave MakeNotFound()
    {
        var _impl = new __impl_(Tags.NotFound);
        return new ResultSave(_impl);
    }

    public readonly bool IsOk
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        get => this._impl._tag == Tags.Ok;
    }
    public readonly bool IsNotFound
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        get => this._impl._tag == Tags.NotFound;
    }

    public int Ok
    {
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        readonly get => !this.IsOk ? default! : this._impl._unmanaged_._0!;
        [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
        set { if (this.IsOk) { this._impl._unmanaged_._0 = value; } }
    }

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly bool Equals(ResultSave other) => this.Tag != other.Tag ? false : this.Tag switch
    {
        Tags.Ok => global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(this.Ok, other.Ok),
        _ => true,
    };

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly override int GetHashCode() => this.Tag switch
    {
        Tags.Ok => global::System.HashCode.Combine(this.Tag, this.Ok),
        _ => global::System.HashCode.Combine(this.Tag),
    };

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly override bool Equals(object? obj) => obj is ResultSave other && Equals(other);

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator ==(ResultSave left, ResultSave right) => Equals(left, right);
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator !=(ResultSave left, ResultSave right) => !Equals(left, right);

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly int CompareTo(ResultSave other) => this.Tag != other.Tag ? global::System.Collections.Generic.Comparer<Tags>.Default.Compare(this.Tag, other.Tag) : this.Tag switch
    {
        Tags.Ok => global::System.Collections.Generic.Comparer<int>.Default.Compare(this.Ok, other.Ok),
        _ => 0,
    };

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator <(ResultSave left, ResultSave right) => left.CompareTo(right) < 0;
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator >(ResultSave left, ResultSave right) => left.CompareTo(right) > 0;
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator <=(ResultSave left, ResultSave right) => left.CompareTo(right) <= 0;
    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public static bool operator >=(ResultSave left, ResultSave right) => left.CompareTo(right) >= 0;

    [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public readonly override string ToString() => this.Tag switch
    {
        Tags.Ok => $"{nameof(ResultSave)}.{nameof(Tags.Ok)} {{ {this.Ok} }}",
        Tags.NotFound => $"{nameof(ResultSave)}.{nameof(Tags.NotFound)}",
        _ => nameof(ResultSave),
    };
}

} // namespace UnionTypesDemo

Code and pdf at

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

RSCG – LightweightObjectMapper

RSCG – LightweightObjectMapper
 
 

name LightweightObjectMapper
nuget https://www.nuget.org/packages/LightweightObjectMapper/
link https://github.com/stratosblue/LightweightObjectMapper
author Stratos

Generating function to map DTOs

 

This is how you can use LightweightObjectMapper .

The code that you start with is


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

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

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

	<ItemGroup>
	  <PackageReference Include="LightweightObjectMapper" Version="1.0.2" />
	</ItemGroup>

	<!--<PropertyGroup>
		<NoLightweightObjectMapperPreCodes>true</NoLightweightObjectMapperPreCodes>
		<LOMappingMethodAccessibility>public</LOMappingMethodAccessibility>
	</PropertyGroup>-->

	
</Project>


The code that you will use is


using mapperDemo;
using LightweightObjectMapper;
var p=new Person();
p.FirstName = "Andrei";
p.LastName = "Ignat";
PersonDTO dto= p.MapTo<PersonDTO>();
Console.WriteLine(dto.FullName);




public partial class Person
{
    public int ID { get; set; }
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
}





namespace mapperDemo;
public partial class PersonDTO
{
    public int ID { get; set; }
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public string FullName { 
        get
        {
            return FirstName + " " + LastName;
        }
    }
}



using LightweightObjectMapper;
using System;
namespace mapperDemo;

[MappingProfile]
internal partial class Extensions:
    IPostMapping<Person, PersonDTO>
{
    

    public PersonDTO PostMapping(Person source, PersonDTO target)
    {
        target.ID = source.ID;
        return target;
    }
}


 

The code that is generated is

// <Auto-Generated/>
#pragma warning disable IDE0005
#pragma warning disable CS0105
using LightweightObjectMapper;
using System;
using System;
using System.Linq;
using System.Runtime.CompilerServices;

namespace mapperDemo
{
    sealed partial class Extensions
    {
        public static partial class Generated
        {
            /// <summary>
            /// PostMappingDeclaration for <see cref = "global::Person"/> to <see cref = "global::mapperDemo.PersonDTO"/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.PostMappingDeclaration, typeof(global::Person), typeof(global::mapperDemo.PersonDTO))]
            public static global::mapperDemo.PersonDTO PostMapping_D275C37F33F4AFBD(global::Person source, global::mapperDemo.PersonDTO target)
            {
                target.ID = source.ID;
                return target;
            }
        }
    }
}
#if !NO_LIGHTWEIGHT_OBJECT_MAPPER_PRE_CODES

// <Auto-Generated/>

#pragma warning disable IDE0161 // 转换为文件范围限定的 namespace

using System;
using System.Collections.Generic;

namespace LightweightObjectMapper
{
    /// <summary>
    /// 映射配置接口
    /// </summary>
    internal interface IMappingProfile { }

    /// <summary>
    /// 映射后执行的动作
    /// </summary>
    /// <typeparam name="TIn"></typeparam>
    /// <typeparam name="TOut"></typeparam>
    internal interface IPostMapping<TIn, TOut> : IMappingProfile
    {
        /// <summary>
        /// 映射后执行的动作
        /// </summary>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        TOut PostMapping(TIn source, TOut target);
    }

    /// <summary>
    /// 映射前准备
    /// </summary>
    /// <typeparam name="TIn"></typeparam>
    /// <typeparam name="TOut"></typeparam>
    internal interface IMappingPrepare<TIn, TOut> : IMappingProfile
    {
        /// <summary>
        /// 映射前准备
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        TOut MappingPrepare(TIn source);
    }

    /// <summary>
    /// 接管完整的类型映射(仅非目标实例映射)
    /// </summary>
    /// <typeparam name="TIn"></typeparam>
    /// <typeparam name="TOut"></typeparam>
    internal interface ITypeMapping<TIn, TOut> : IMappingProfile
    {
        /// <summary>
        /// 接管完整的类型映射(仅非目标实例映射)
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        TOut TypeMapping(TIn source);
    }

    /// <summary>
    /// 类型成员忽略映射
    /// </summary>
    /// <typeparam name="T"></typeparam>
    internal interface ITypeMemberIgnoreMapping<T> : IMappingProfile
    {
        /// <summary>
        /// 类型成员忽略映射<br/>
        /// 方法体内访问过的 <paramref name="target"/> 所有成员,将在映射时被忽略
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        object? IgnoreMapping(T target);
    }

    /// <summary>
    /// 标记一个方法为集合映射方法<br/>
    /// 集合映射方法应包含唯一泛型参数 T ,以及唯一参数 <see cref="IEnumerable{T}"/> ,返回类型应该为 <see cref="IEnumerable{T}"/> 的派生类型
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    internal sealed class CollectionMappingAttribute : Attribute
    {
    }

    /// <summary>
    /// 标记类为映射配置类
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    internal sealed class MappingProfileAttribute : Attribute
    {
        /// <inheritdoc cref="MappingProfileAttribute"/>
        public MappingProfileAttribute() { }
    }

    /// <summary>
    /// 映射元数据
    /// </summary>
    [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
    internal sealed class MappingMetadataAttribute : Attribute
    {
        /// <inheritdoc cref="MappingMetadataAttribute"/>
        public MappingMetadataAttribute(MappingMetadataType type, params object[] data) { }
    }

    /// <summary>
    /// 映射元数据类型
    /// </summary>
    internal enum MappingMetadataType
    {
        /// <summary>
        /// 声明 MappingPrepare
        /// </summary>
        MappingPrepareDeclaration,

        /// <summary>
        /// 声明 PostMapping
        /// </summary>
        PostMappingDeclaration,

        /// <summary>
        /// 声明 TypeMapping
        /// </summary>
        TypeMappingDeclaration,

        /// <summary>
        /// 声明 CollectionMapping
        /// </summary>
        CollectionMappingDeclaration,

        /// <summary>
        /// 忽略成员声明
        /// </summary>
        IgnoreMembersDeclaration,

        /// <summary>
        /// 类型忽略成员声明
        /// </summary>
        TypeIgnoreMembersDeclaration,
    }

    /// <summary>
    /// 引用其它映射配置类
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
    internal sealed class MappingProfileIncludeAttribute : Attribute
    {
        /// <inheritdoc cref="MappingProfileIncludeAttribute"/>
        public MappingProfileIncludeAttribute(params Type[] profileTypes) { }
    }

    /// <summary>
    /// 对象映射 MapTo 占位方法
    /// </summary>
    [Obsolete("Do not use the placeholder extension class.", true)]
    internal static class LightweightObjectMapperPlaceholderExtensions
    {
        private const string ErrorCallPlaceholderMethodMessage = "Do not use the placeholder extension method. If not redirect to the right mapper extension method please try fix other errors and rebuild the project.";

        /// <summary>
        /// 对象映射 MapTo 占位方法<br/>
        /// 生成 无需目标对象 的泛型映射方法,映射到 <typeparamref name="TOut"/>
        /// </summary>
        /// <typeparam name="TOut"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        [Obsolete(ErrorCallPlaceholderMethodMessage, true)]
        public static TOut MapTo<TOut>(this object source)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 对象映射 MapTo 占位方法<br/>
        /// 生成 需要目标对象 的泛型映射方法,映射到 <typeparamref name="TOut"/>
        /// </summary>
        /// <typeparam name="TOut"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        [Obsolete(ErrorCallPlaceholderMethodMessage, true)]
        public static TOut MapTo<TOut>(this object source, TOut target)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 值类型 对象映射 MapTo 占位方法<br/>
        /// 生成 需要目标值类型对象 的泛型映射方法,映射到 <typeparamref name="TOut"/>
        /// </summary>
        /// <typeparam name="TOut"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        [Obsolete(ErrorCallPlaceholderMethodMessage, true)]
        public static TOut MapTo<TOut>(this object source, ref TOut target)
            where TOut : struct
        {
            throw new NotImplementedException();
        }
    }
}

#endif

#if !NO_LIGHTWEIGHT_OBJECT_MAPPER_PRE_CODES

// <Auto-Generated/>

#pragma warning disable IDE0161 // 转换为文件范围限定的 namespace

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;

namespace LightweightObjectMapper
{
    /// <summary>
    /// 预定义的类型映射
    /// </summary>
    [MappingProfile]
    internal sealed partial class PredefinedSpecialTypeMapping
        : ITypeMapping<int, bool>
        , ITypeMapping<short, bool>
        , ITypeMapping<long, bool>
    {
        public bool TypeMapping(int source)
        {
            return source != 0;
        }

        public bool TypeMapping(short source)
        {
            return source != 0;
        }

        bool ITypeMapping<long, bool>.TypeMapping(long source)
        {
            return source != 0;
        }

        [CollectionMapping]
        public static IEnumerable<T>? ToIEnumerable<T>(IEnumerable<T>? items)
        {
            return items?.ToList();
        }

        [CollectionMapping]
        public static ICollection<T>? ToICollection<T>(IEnumerable<T>? items)
        {
            return items?.ToList();
        }

        [CollectionMapping]
        public static IReadOnlyCollection<T>? ToIReadOnlyCollection<T>(IEnumerable<T>? items)
        {
            return items?.ToList();
        }

        [CollectionMapping]
        public static IList<T>? ToIList<T>(IEnumerable<T>? items)
        {
            return items?.ToList();
        }

        [CollectionMapping]
        public static IReadOnlyList<T>? ToIReadOnlyList<T>(IEnumerable<T>? items)
        {
            return items?.ToList();
        }

        [CollectionMapping]
        public static List<T>? ToList<T>(IEnumerable<T>? items)
        {
            return items?.ToList();
        }
    }
}

#endif

// <Auto-Generated/>
#pragma warning disable IDE0005
#pragma warning disable CS0105
using System;
using System.Linq;
using System.Runtime.CompilerServices;

namespace LightweightObjectMapper
{
    internal static partial class LOMMapExtensions_mapperDemo
    {
        /// <summary>
        /// Map <see cref = "global::Person"/> to the following types:<br/>
        /// <see cref = "global::mapperDemo.PersonDTO"/><br/>
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static TOut MapTo<TOut>(this global::Person source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (typeof(TOut) == typeof(global::mapperDemo.PersonDTO))
            {
                var target = new global::mapperDemo.PersonDTO()
                {
                    LastName = source.LastName,
                    ID = source.ID,
                    FirstName = source.FirstName,
                };
                target = global::mapperDemo.Extensions.Generated.PostMapping_D275C37F33F4AFBD(source, target);
                return (TOut)(target as object);
            }

            throw new global::System.NotImplementedException($"No mapping code for {typeof(TOut)}.");
        }
    }
}
// <Auto-Generated/>
#pragma warning disable IDE0005
#pragma warning disable CS0105
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System;
using System.Linq;
using System.Runtime.CompilerServices;

namespace LightweightObjectMapper
{
    sealed partial class PredefinedSpecialTypeMapping
    {
        public static partial class Generated
        {
            /// <summary>
            /// TypeMappingDeclaration for <see cref = "int "/> to <see cref = "bool "/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.TypeMappingDeclaration, typeof(int), typeof(bool))]
            public static bool TypeMapping_A07AFC9A322FFA04(int source)
            {
                return source != 0;
            }

            /// <summary>
            /// TypeMappingDeclaration for <see cref = "short "/> to <see cref = "bool "/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.TypeMappingDeclaration, typeof(short), typeof(bool))]
            public static bool TypeMapping_946949E7222BC174(short source)
            {
                return source != 0;
            }

            /// <summary>
            /// TypeMappingDeclaration for <see cref = "long "/> to <see cref = "bool "/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.TypeMappingDeclaration, typeof(long), typeof(bool))]
            public static bool TypeMapping_3C4D395B4EF43E87(long source)
            {
                return source != 0;
            }

            /// <summary>
            /// CollectionMappingDeclaration for <see cref = "global::System.Collections.Generic.IEnumerable{T}"/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.CollectionMappingDeclaration, typeof(global::System.Collections.Generic.IEnumerable<>))]
            public static global::System.Collections.Generic.IEnumerable<T> CollectionMapping_CEFAD35E246FD0F7<T>(global::System.Collections.Generic.IEnumerable<T> items)
            {
                return items?.ToList();
            }

            /// <summary>
            /// CollectionMappingDeclaration for <see cref = "global::System.Collections.Generic.ICollection{T}"/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.CollectionMappingDeclaration, typeof(global::System.Collections.Generic.ICollection<>))]
            public static global::System.Collections.Generic.ICollection<T> CollectionMapping_37FFD1A2226B51E9<T>(global::System.Collections.Generic.IEnumerable<T> items)
            {
                return items?.ToList();
            }

            /// <summary>
            /// CollectionMappingDeclaration for <see cref = "global::System.Collections.Generic.IReadOnlyCollection{T}"/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.CollectionMappingDeclaration, typeof(global::System.Collections.Generic.IReadOnlyCollection<>))]
            public static global::System.Collections.Generic.IReadOnlyCollection<T> CollectionMapping_AF82A9960EE0C495<T>(global::System.Collections.Generic.IEnumerable<T> items)
            {
                return items?.ToList();
            }

            /// <summary>
            /// CollectionMappingDeclaration for <see cref = "global::System.Collections.Generic.IList{T}"/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.CollectionMappingDeclaration, typeof(global::System.Collections.Generic.IList<>))]
            public static global::System.Collections.Generic.IList<T> CollectionMapping_284BCB723CA17B0E<T>(global::System.Collections.Generic.IEnumerable<T> items)
            {
                return items?.ToList();
            }

            /// <summary>
            /// CollectionMappingDeclaration for <see cref = "global::System.Collections.Generic.IReadOnlyList{T}"/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.CollectionMappingDeclaration, typeof(global::System.Collections.Generic.IReadOnlyList<>))]
            public static global::System.Collections.Generic.IReadOnlyList<T> CollectionMapping_976EA1DB5B772C59<T>(global::System.Collections.Generic.IEnumerable<T> items)
            {
                return items?.ToList();
            }

            /// <summary>
            /// CollectionMappingDeclaration for <see cref = "global::System.Collections.Generic.List{T}"/>
            /// </summary>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            [MappingMetadata(MappingMetadataType.CollectionMappingDeclaration, typeof(global::System.Collections.Generic.List<>))]
            public static global::System.Collections.Generic.List<T> CollectionMapping_070F0D0F908DAF14<T>(global::System.Collections.Generic.IEnumerable<T> items)
            {
                return items?.ToList();
            }
        }
    }
}

Code and pdf at

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

RSCG – Enhanced.GetTypes

RSCG – Enhanced.GetTypes
 
 

name Enhanced.GetTypes
nuget https://www.nuget.org/packages/Enhanced.GetTypes/
link https://github.com/duskembayev/Enhanced.GetTypes
author duskembayev

Generating list of PUBLIC classes that implements an interface

 

This is how you can use Enhanced.GetTypes .

The code that you start with is


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

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

  <ItemGroup>
    <PackageReference Include="Enhanced.GetTypes" Version="1.0.0" />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


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

Console.WriteLine("Hello, World!");
foreach (var type in ProjectTypes.GetIPersonTypes())
{
    Console.WriteLine(type.Name);
}


using Enhanced.GetTypes.Annotation;

namespace GetTypesForInterface;
public partial class ProjectTypes
{
    [DerivedTypes(typeof(IPerson))]
    public  static partial IEnumerable<Type> GetIPersonTypes();
}




namespace GetTypesForInterface;
internal interface IPerson
{
    public string Name { get; set; }
}




namespace GetTypesForInterface;
public class Student : IPerson
{
    public string Name { get; set; } = "";
}
    



namespace GetTypesForInterface;
public class Teacher:IPerson
{
    public string Name { get; set; } = "";
}



 

The code that is generated is

// <auto-generated />
namespace GetTypesForInterface
{
    partial class ProjectTypes
    {
        public static partial System.Collections.Generic.IEnumerable<System.Type> GetIPersonTypes()
        {
            yield return typeof(GetTypesForInterface.Student);
            yield return typeof(GetTypesForInterface.Teacher);
            yield break;
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Enhanced.GetTypes

RSCG – Immediate.Handlers

RSCG – Immediate.Handlers
 
 

name Immediate.Handlers
nuget https://www.nuget.org/packages/Immediate.Handlers/
link https://github.com/immediateplatform/Immediate.Handlers
author Stuart Turner

Generating mediator like handlers

 

This is how you can use Immediate.Handlers .

The code that you start with is


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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	<ItemGroup>
		<PackageReference Include="Immediate.Handlers" Version="1.6.1" />
		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
		<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />		
	</ItemGroup>

</Project>


The code that you will use is



Console.WriteLine("Hello, World!");
ServiceCollection services = new ();
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
services.AddSingleton(typeof(ILogger<>), typeof(NullLogger<>));
services.AddHandlers();
services.AddBehaviors();
IHandler<Ping, Pong> handler = services.BuildServiceProvider().GetRequiredService<IHandler<Ping, Pong>>();
var id = Guid.NewGuid();
var request = new Ping(id);
var pong = await handler.HandleAsync(request, CancellationToken.None);
Console.WriteLine($"Got pong with id {pong.Id}!");



using Immediate.Handlers.Shared;

public sealed record Ping(Guid Id);// : IRequest<Pong>;

public sealed record Pong(Guid Id);


[Handler]
[Behaviors(
    typeof(LoggingBehavior<,>)
)]
public static partial class PingHandler //: IPipelineAction<Ping, Pong>
{

    private static async ValueTask<Pong> HandleAsync(Ping request, CancellationToken token)
    {
        await Task.Delay(1000);
        Console.WriteLine("Returning pong!");
        return new Pong(request.Id);
    }
}




public sealed class LoggingBehavior<TRequest, TResponse>(ILogger<LoggingBehavior<TRequest, TResponse>>? logger)
    : Behavior<TRequest, TResponse>
{
    public override async ValueTask<TResponse> HandleAsync(TRequest request, CancellationToken cancellationToken)
    {
        Console.WriteLine("I am a logging behaviour");
        logger?.LogInformation("LoggingBehavior.Enter");
        var response = await Next(request, cancellationToken);
        logger?.LogInformation("LoggingBehavior.Exit");
        return response;
    }
}


global using Microsoft.Extensions.DependencyInjection;
global using Immediate.Handlers.Shared;
global using Microsoft.Extensions.Logging;
global using Mediator;
global using Microsoft.Extensions.Logging.Abstractions;


 

The code that is generated is

using Microsoft.Extensions.DependencyInjection;

#pragma warning disable CS1591

partial class PingHandler
{
	public sealed partial class Handler : global::Immediate.Handlers.Shared.IHandler<global::Ping, global::Pong>
	{
		private readonly global::PingHandler.HandleBehavior _handleBehavior;
		private readonly global::LoggingBehavior<global::Ping, global::Pong> _loggingBehavior;

		public Handler(
			global::PingHandler.HandleBehavior handleBehavior,
			global::LoggingBehavior<global::Ping, global::Pong> loggingBehavior
		)
		{
			var handlerType = typeof(PingHandler);

			_handleBehavior = handleBehavior;

			_loggingBehavior = loggingBehavior;
			_loggingBehavior.HandlerType = handlerType;

			_loggingBehavior.SetInnerHandler(_handleBehavior);
		}

		public async global::System.Threading.Tasks.ValueTask<global::Pong> HandleAsync(
			global::Ping request,
			global::System.Threading.CancellationToken cancellationToken = default
		)
		{
			return await _loggingBehavior
				.HandleAsync(request, cancellationToken)
				.ConfigureAwait(false);
		}
	}

	[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
	public sealed class HandleBehavior : global::Immediate.Handlers.Shared.Behavior<global::Ping, global::Pong>
	{

		public HandleBehavior(
		)
		{
		}

		public override async global::System.Threading.Tasks.ValueTask<global::Pong> HandleAsync(
			global::Ping request,
			global::System.Threading.CancellationToken cancellationToken
		)
		{
			return await global::PingHandler
				.HandleAsync(
					request
					, cancellationToken
				)
				.ConfigureAwait(false);
		}
	}

	[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
	public static IServiceCollection AddHandlers(
		IServiceCollection services,
		ServiceLifetime lifetime = ServiceLifetime.Scoped
	)
	{
		services.Add(new(typeof(global::PingHandler.Handler), typeof(global::PingHandler.Handler), lifetime));
		services.Add(new(typeof(global::Immediate.Handlers.Shared.IHandler<global::Ping, global::Pong>), typeof(global::PingHandler.Handler), lifetime));
		services.Add(new(typeof(global::PingHandler.HandleBehavior), typeof(global::PingHandler.HandleBehavior), lifetime));
		return services;
	}
}

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

#pragma warning disable CS1591

namespace Mediator;

public static class HandlerServiceCollectionExtensions
{
	public static IServiceCollection AddBehaviors(
		this IServiceCollection services)
	{
		services.TryAddTransient(typeof(global::LoggingBehavior<,>));
		
		return services;
	}

	public static IServiceCollection AddHandlers(
		this IServiceCollection services,
		ServiceLifetime lifetime = ServiceLifetime.Scoped
	)
	{
		global::PingHandler.AddHandlers(services, lifetime);
		
		return services;
	}
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Immediate.Handlers

NetCoreUsefullEndpoints-part 13–adding runtime information

In the Nuget NetCoreUsefullEndpoints I have added information about the runtime information :

You can access by going to localhost:5027/api/usefull/runtimeinformationAll and the end result is

{
“frameworkDescription”: “.NET 8.0.8”,
“osDescription”: “Microsoft Windows 10.0.22631”,
“processArchitecture”: “X64”,
“osArchitecture”: “X64”
}

The code that returns this is

route.MapGet("api/usefull/runtimeinformation/", (HttpContext httpContext) =>
        {
            return TypedResults.Ok(new Helper().FromStaticRuntimeInformation());
        })

( I have used a Roslyn Code Generator , https://ignatandrei.github.io/RSCG_Examples/v2/docs/RSCG_Static#example–source-csproj-source-files- , that generates a class from a static class )

NetCoreUsefullEndpoints-part 12–adding url adresses

In the Nuget NetCoreUsefullEndpoints I have added information about the current process :

You can access by going to localhost:5027/api/usefull/adresses and the end result is

[
     “http://localhost:5027″
]

The code that returns this is

route.MapGet("api/usefull/adresses", (HttpContext httpContext, [FromServices] IServer server) =>
        {
            var adresses = server.Features.Get<IServerAddressesFeature>();
            var ret= adresses?.Addresses?.ToArray()??[] ;
            return TypedResults.Ok(ret);
        });

NetCoreUsefullEndpoints-part 11–adding process information

In the Nuget NetCoreUsefullEndpoints I have added information about the current process :

You can access by going to

http://localhost:5027/api/usefull/process

and this is the result

{
     “id”: 24064,
     “processName”: “TestUsefullEndpoints”,
     “startTime”: “2024-06-27T23:24:36.4003351+03:00”,
     “totalProcessorTime”: “00:00:01.0312500”,
     “threadsCount”: 39,
     “workingSet64”: 84385792,
     “privateMemorySize64”: 65458176,
     “pagedMemorySize64”: 65458176,
     “pagedSystemMemorySize64”: 384840,
     “peakPagedMemorySize64”: 67108864,
     “peakVirtualMemorySize64”: 2481013948416,
     “peakWorkingSet64”: 84733952,
     “virtualMemorySize64”: 2481005563904,
     “basePriority”: 8,
     “handleCount”: 592,
     “machineName”: “.”,
     “priorityClassName”: “Normal”,
     “priorityClass”: 32,
     “nonpagedSystemMemorySize64”: 91992,
     “fileName”: “D:\\gth\\NetCoreUsefullEndpoints\\src\\UsefullEndpoints\\TestUsefullEndpoints\\bin\\Debug\\net8.0\\TestUsefullEndpoints.exe”,
     “minWorkingSet”: 204800,
     “maxWorkingSet”: 1413120,
     “totalProcessorTimeSeconds”: 1.03125,
     “totalUserProcessorTimeSeconds”: 0.921875,
     “totalPrivilegedProcessorTimeSeconds”: 0.109375,
     “fileVersionInfoShort”: {
         “fileVersion”: “1.0.0.0”,
         “fileName”: “D:\\gth\\NetCoreUsefullEndpoints\\src\\UsefullEndpoints\\TestUsefullEndpoints\\bin\\Debug\\net8.0\\TestUsefullEndpoints.exe”,
         “fileDescription”: “TestUsefullEndpoints”,
         “originalFilename”: “TestUsefullEndpoints.dll”,
         “productVersion”: “1.0.0+7f426dfd54f515a95654044b725010b159c89b2f”
     },
     “fileVersionInfo”: {
         “comments”: “”,
         “companyName”: “TestUsefullEndpoints”,
         “fileBuildPart”: 0,
         “fileDescription”: “TestUsefullEndpoints”,
         “fileMajorPart”: 1,
         “fileMinorPart”: 0,
         “fileName”: “D:\\gth\\NetCoreUsefullEndpoints\\src\\UsefullEndpoints\\TestUsefullEndpoints\\bin\\Debug\\net8.0\\TestUsefullEndpoints.exe”,
         “filePrivatePart”: 0,
         “fileVersion”: “1.0.0.0”,
         “internalName”: “TestUsefullEndpoints.dll”,
         “isDebug”: false,
         “isPatched”: false,
         “isPrivateBuild”: false,
         “isPreRelease”: false,
         “isSpecialBuild”: false,
         “language”: “Language Neutral”,
         “legalCopyright”: ” “,
         “legalTrademarks”: “”,
         “originalFilename”: “TestUsefullEndpoints.dll”,
         “privateBuild”: “”,
         “productBuildPart”: 0,
         “productMajorPart”: 1,
         “productMinorPart”: 0,
         “productName”: “TestUsefullEndpoints”,
         “productPrivatePart”: 0,
         “productVersion”: “1.0.0+7f426dfd54f515a95654044b725010b159c89b2f”,
         “specialBuild”: “”
     }
}

And now , because it is version and calendar dependent it is now 8.2024.627.800 ( 8 means .net 8 , then year.monthday.hourminutes) . It is convenient, because you know what version to use ;

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.