Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user