using Omu.ValueInjecter; using Omu.ValueInjecter.Injections; using System; using System.Collections.Generic; using System.ComponentModel; using System.Reflection; namespace Infrastructure.Extensions { public static class ObjectMapperExtensions { public static T From(this T target, object source, bool skipNull = false, List skips = null, bool skipReadonly = false) { var injection = new NullableInjection { SkipNull = skipNull, SkipReadonly = skipReadonly }; if (skips != null) { injection.SkipProperties.AddRange(skips); } return (T)target.InjectFrom(injection, source); } public static T To(this object source, bool skipNull = false, List skips = null) { var injection = new NullableInjection { SkipNull = skipNull }; if (skips != null) { injection.SkipProperties.AddRange(skips); } return (T)(Activator.CreateInstance(typeof(T)).InjectFrom(injection, source)); } // public static T FromDto(this T target, object source) { var injection = new NullableInjection { SkipFunc = o => o.Name.EndsWith("Id", StringComparison.Ordinal) }; return (T)target.InjectFrom(injection, source); } } public class NullableInjection : LoopInjection { public bool SkipNull { get; set; } public List SkipProperties { get; } = new List(); public Func SkipFunc { get; set; } public bool SkipReadonly { get; set; } protected override bool MatchTypes(Type sourceType, Type targetType) { var snt = Nullable.GetUnderlyingType(sourceType); var tnt = Nullable.GetUnderlyingType(targetType); return sourceType == targetType || sourceType == tnt || targetType == snt; } protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) { if (sp is null) { throw new ArgumentNullException(nameof(sp)); } if (this.SkipNull) { var value = sp.GetValue(source); if (value == null) { return; } } if (this.SkipProperties != null && this.SkipProperties.Count > 0) { if (this.SkipProperties.Contains(sp.Name)) { return; } } if (this.SkipFunc != null) { if (this.SkipFunc(sp)) { return; } } if (this.SkipReadonly && sp.GetCustomAttribute() != null) { return; } base.SetValue(source, target, sp, tp); } } }