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
Leave a Reply