RSCG – NextGenMapper

RSCG – NextGenMapper
 
 

name NextGenMapper
nuget https://www.nuget.org/packages/NextGenMapper/
link https://github.com/DedAnton/NextGenMapper
author Anton Ryabchikov

Automating generating mapping between classes

 

This is how you can use NextGenMapper .

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="NextGenMapper" Version="0.1.0-alpha.13" OutputItemType="Analyzer"  />
  </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 NextGenMapperDemo;

using NextGenMapper;

//var source = new Source("Anton", 25);

//var destination = source.Map<Destination>();

//Console.WriteLine(destination);


//record Source(string Name, int Age);
//record Destination(string Name, int Age);

Person p = new();
p.Name = "Andrei Ignat";
p.Country_Name = "Romania";

var dto = p.MapWith<PersonDTO>(
    BirthCountry:new Country()
    {
        CountryCode=p.Country_CountryCode,
        Name=p.Country_Name
    });

//Name is automatically mapped
Console.WriteLine(dto.Name);
Console.WriteLine(dto.BirthCountry!.Name);




namespace NextGenMapperDemo;

internal class Person
{
    public int ID { get; set; } 
    public string? Name { get; set; }
    public string? Country_Name { get; set; }
    public string? Country_CountryCode { get; set; }
}






namespace NextGenMapperDemo;
internal class Country
{

    public string? Name { get; set; }
    public string? CountryCode { get; set; }
}
internal class PersonDTO
{
    public int Id { get; set; }
    public string? Name { get; set; }
    public Country? BirthCountry { get; set; }
}


 

The code that is generated is

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

namespace NextGenMapper.Extensions
{
    internal static class MapperExtensions
    {
        /// <summary>
        /// Do not use this method, for auto-generated mapper only!
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static bool TryGetSpan<TSource>(this IEnumerable<TSource> source, out ReadOnlySpan<TSource> span)
        {
            bool result = true;
            if (source.GetType() == typeof(TSource[]))
            {
                span = Unsafe.As<TSource[]>(source);
            }
            #if NET5_0_OR_GREATER
            else if (source.GetType() == typeof(List<TSource>))
            {
                span = CollectionsMarshal.AsSpan(Unsafe.As<List<TSource>>(source));
            }
            #endif
            else
            {
                span = default;
                result = false;
            }

            return result;
        }
    }
}
#nullable enable
using NextGenMapper.Extensions;

namespace NextGenMapper
{
    internal static partial class Mapper
    {
        internal static NextGenMapperDemo.PersonDTO Map<To>(this NextGenMapperDemo.Person source) => new NextGenMapperDemo.PersonDTO()
        {
            Name = source.Name
        };
    }
}
#nullable enable
using NextGenMapper.Extensions;

namespace NextGenMapper
{
    internal static partial class Mapper
    {
        internal static NextGenMapperDemo.PersonDTO MapWith<To>
        (
            this NextGenMapperDemo.Person source,
            NextGenMapperDemo.Country BirthCountry
        )
        => new NextGenMapperDemo.PersonDTO
        {
            Name = source.Name,
            BirthCountry = BirthCountry
        };
    }
}
#nullable enable
using NextGenMapper.Extensions;

namespace NextGenMapper
{
    internal static partial class Mapper
    {
        internal static NextGenMapperDemo.PersonDTO MapWith<To>
        (
            this NextGenMapperDemo.Person source,
            int Id = default!,
            string? Name = default!,
            NextGenMapperDemo.Country? BirthCountry = default!
        )
        {
            throw new System.NotImplementedException("This method is a mock and is not intended to be called");
        }
    }
}
using System;
using System.Linq;

namespace NextGenMapper
{
    internal static partial class Mapper
    {
        internal static To Map<To>(this object source) => throw new InvalidOperationException($"Error when mapping {source.GetType()} to {typeof(To)}, mapping function was not found. Create custom mapping function.");

        internal static To MapWith<To>(this object source) => throw new InvalidOperationException($"Error when mapping {source.GetType()} to {typeof(To)}, mapping function was not found. Create custom mapping function.");
    
        internal static To Project<To>(this IQueryable<object> source) => throw new InvalidOperationException($"Error when project {source.GetType()} to {typeof(To)}, project function was not found.");
        
        internal static To ProjectWith<To>(this IQueryable<object> source) => throw new InvalidOperationException($"Error when project {source.GetType()} to {typeof(To)}, project function was not found.");
        
        internal static To Project<To>(this IQueryable source) => throw new InvalidOperationException($"Error when project {source.GetType()} to {typeof(To)}, projection for non generic IQueryable is not supported");

        internal static To ProjectWith<To>(this IQueryable source) => throw new InvalidOperationException($"Error when project {source.GetType()} to {typeof(To)}, projection for non generic IQueryable is not supported");
    }
}

Code and pdf at

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