You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iot/labs/Teacher/Infrastructure/Extensions/ObjectMapperExtensions.cs

110 lines
3.5 KiB

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<T>(this T target, object source, bool skipNull = false, string[] 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<T>(this object source, bool skipNull = false, List<string> 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<T>(this T target, object source)
{
var injection = new NullableInjection
{
SkipFunc = o => o.Name.EndsWith("Id", StringComparison.Ordinal)
};
return (T)target.InjectFrom(injection, source);
}
public static T FromWhere<T>(this T target, object source, Func<PropertyInfo,PropertyInfo,bool> update)
{
var injection = new NullableInjection { update = update };
return (T)target.InjectFrom(injection, source);
}
}
public class NullableInjection : LoopInjection
{
public bool SkipNull { get; set; }
public List<string> SkipProperties { get; } = new List<string>();
public Func<PropertyInfo, bool> SkipFunc { get; set; }
public bool SkipReadonly { get; set; }
public Func<PropertyInfo, PropertyInfo,bool> update { 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(this.update is not null)
{
if(!update.Invoke(sp,tp))
{
return;
}
}
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<ReadOnlyAttribute>() != null)
{
return;
}
base.SetValue(source, target, sp, tp);
}
}
}