using System; using System.Collections; using System.ComponentModel; using System.Linq; using System.Reflection; using Omu.ValueInjecter; using Omu.ValueInjecter.Injections; namespace Infrastructure.Extensions { public static class ObjectMapperExtensions { public static T From(this T target, object source, bool skipNullObject = false) { if (skipNullObject) { return (T)target.InjectFrom(source); } else { return (T)target.InjectFrom(source); } } public static T FromPlain(this T target, object source, params string[] skip) { return (T)target.InjectFrom(new PlainInjection(skip), source); } public static T To(this object source) { return (T)(Activator.CreateInstance(typeof(T)).InjectFrom(source)); } public static T Update(this T target, object source, params string[] skips) { return (T)target.InjectFrom(new PlainInjection(skips), source); } } public class NullableInjection : LoopInjection { 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) { base.SetValue(source, target, sp, tp); } } public class SkipNullObjectInjection : NullableInjection { protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) { var value = sp.GetValue(source); if (value == null) { return; } base.SetValue(source, target, sp, tp); } } public class PlainInjection : LoopInjection { private readonly string[] _skip; public PlainInjection(params string[] skip) { this._skip = skip; } protected override bool MatchTypes(Type sourceType, Type targetType) { if (sourceType.IsClass && sourceType != typeof(string)) { return false; } if (typeof(ICollection).IsAssignableFrom(sourceType)) { return false; } return base.MatchTypes(sourceType, targetType); } protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp) { if (this._skip != null && this._skip.Length > 0) { if (this._skip.Contains(sp.Name)) { return; } } base.SetValue(source, target, sp, tp); } } }