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