Files

57 lines
1.9 KiB
C#

using System.Dynamic;
using System.Reflection;
namespace adas_core.Domain.Utils;
public static class Mapper<T>
// We can only use reference types
where T : class
{
private static readonly Dictionary<string, PropertyInfo> PropertyMap;
static Mapper()
{
// At this point we can convert each
// property name to lower case so we avoid
// creating a new string more than once.
PropertyMap =
typeof(T)
.GetProperties()
.ToDictionary(
p => p.Name.ToLower(),
p => p
);
}
public static void Map(ExpandoObject source, T destination)
{
// Might as well take care of null references early.
if (source == null) throw new ArgumentNullException(nameof(source));
if (destination == null) throw new ArgumentNullException(nameof(destination));
// By iterating the KeyValuePair<string, object> of
// source we can avoid manually searching the keys of
// source as we see in your original code.
foreach (var kv in source)
if (PropertyMap.TryGetValue(kv.Key.ToLower(), out var p))
{
var propType = p.PropertyType;
if (kv.Value == null)
{
if (propType is { IsByRef: false } && propType.Name != "Nullable`1")
// Throw if type is a value type
// but not Nullable<>
throw new ArgumentException("not nullable");
}
else if (kv.Value.GetType() != propType)
{
// You could make this a bit less strict
// but I don't recommend it.
p.SetValue(destination, Convert.ToDouble(kv.Value), null);
}
p.SetValue(destination, kv.Value, null);
}
}
}