2022-03-20 10:10:44 +04:00
|
|
|
|
using System;
|
2021-08-20 18:28:34 +04:00
|
|
|
|
using System.Collections;
|
2022-03-18 13:27:14 +04:00
|
|
|
|
using System.Linq;
|
2021-03-28 19:15:55 +04:00
|
|
|
|
using System.Reflection;
|
2022-03-20 10:10:44 +04:00
|
|
|
|
using ToolsModule.ManagmentSecurity;
|
2021-03-28 19:15:55 +04:00
|
|
|
|
|
2022-03-20 10:10:44 +04:00
|
|
|
|
namespace ToolsModule.ManagmentMapping
|
2021-03-28 19:15:55 +04:00
|
|
|
|
{
|
2022-03-18 13:27:14 +04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Маппер сущностей
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class Mapper
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Преобразование из одного класса в другой
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="From"></typeparam>
|
|
|
|
|
/// <typeparam name="To"></typeparam>
|
|
|
|
|
/// <param name="obj"></param>
|
|
|
|
|
/// <param name="haveRigth"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static To MapToClass<From, To>(From obj, bool haveRigth) where To : class => FillObject(obj, (To)Activator.CreateInstance(typeof(To)), haveRigth);
|
2021-03-28 19:15:55 +04:00
|
|
|
|
|
2022-03-18 13:27:14 +04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Преобразование из одного класса в другой
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="From"></typeparam>
|
|
|
|
|
/// <typeparam name="To"></typeparam>
|
|
|
|
|
/// <param name="obj"></param>
|
|
|
|
|
/// <param name="newObject"></param>
|
|
|
|
|
/// <returns></returns>
|
2022-03-19 11:53:10 +04:00
|
|
|
|
public static To MapToClass<From, To>(From obj, To newObject, bool haveRigth) where To : class => FillObject(obj, newObject, haveRigth, true);
|
2021-03-28 19:15:55 +04:00
|
|
|
|
|
2022-03-18 13:27:14 +04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Заполнение объекта
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <typeparam name="From"></typeparam>
|
|
|
|
|
/// <typeparam name="To"></typeparam>
|
|
|
|
|
/// <param name="obj"></param>
|
|
|
|
|
/// <param name="newObject"></param>
|
|
|
|
|
/// <param name="haveRigth"></param>
|
2022-03-19 11:53:10 +04:00
|
|
|
|
/// <param name="exsistRecord"></param>
|
2022-03-18 13:27:14 +04:00
|
|
|
|
/// <returns></returns>
|
2022-03-19 11:53:10 +04:00
|
|
|
|
private static To FillObject<From, To>(From obj, To newObject, bool haveRigth, bool exsistRecord = false)
|
2022-03-18 13:27:14 +04:00
|
|
|
|
where To : class
|
|
|
|
|
{
|
|
|
|
|
if (obj == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
if (newObject == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2022-03-19 11:53:10 +04:00
|
|
|
|
|
2022-03-18 13:27:14 +04:00
|
|
|
|
var typeFrom = typeof(From);
|
|
|
|
|
var typeTo = typeof(To);
|
|
|
|
|
var properties = typeTo.GetProperties().Where(x => x.CanWrite);
|
|
|
|
|
foreach (var property in properties)
|
|
|
|
|
{
|
2022-03-19 11:53:10 +04:00
|
|
|
|
if (property.Name == "Id" && exsistRecord)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-03-18 13:27:14 +04:00
|
|
|
|
var checkRight = property.GetCustomAttribute<CheckRigthForMapAttribute>();
|
|
|
|
|
if (!haveRigth && checkRight != null)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-03-18 11:16:29 +04:00
|
|
|
|
|
2022-03-18 20:09:15 +04:00
|
|
|
|
object value = null;
|
2022-03-18 13:27:14 +04:00
|
|
|
|
var customAttribute = property.GetCustomAttribute<MapConfigurationAttribute>();
|
|
|
|
|
if (customAttribute != null)
|
|
|
|
|
{
|
|
|
|
|
if (!haveRigth && !customAttribute.AllowCopyWithoutRigth)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
value = GetValueFromCustomAttribute(customAttribute, typeFrom, obj);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-03-18 20:09:15 +04:00
|
|
|
|
var bindingProperty = typeFrom.GetProperty(property.Name);
|
2022-03-18 13:27:14 +04:00
|
|
|
|
if (bindingProperty != null)
|
|
|
|
|
{
|
|
|
|
|
value = bindingProperty.GetValue(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (value is null)
|
2022-03-18 12:57:40 +04:00
|
|
|
|
{
|
2022-03-18 13:27:14 +04:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (property.PropertyType.Name.StartsWith("Nullable") && Nullable.GetUnderlyingType(property.PropertyType).IsEnum)
|
|
|
|
|
{
|
|
|
|
|
property.SetValue(newObject, Enum.Parse(Nullable.GetUnderlyingType(property.PropertyType), value.ToString()));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
property.SetValue(newObject, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newObject;
|
|
|
|
|
}
|
2021-03-28 19:15:55 +04:00
|
|
|
|
|
2022-03-18 13:27:14 +04:00
|
|
|
|
private static object GetValueFromCustomAttribute(MapConfigurationAttribute customAttribute, Type typeFrom, object obj)
|
|
|
|
|
{
|
|
|
|
|
object value = obj;
|
2022-03-20 19:27:50 +04:00
|
|
|
|
var props = customAttribute.PropertyNameFromModel.Split('.');
|
|
|
|
|
foreach (var prop in props)
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
2022-03-20 19:27:50 +04:00
|
|
|
|
if (prop == "ToString")
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
2022-03-20 19:27:50 +04:00
|
|
|
|
value = value.ToString();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (prop == "Count")
|
|
|
|
|
{
|
|
|
|
|
value = (value as ICollection)?.Count;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (prop == "Method")
|
|
|
|
|
{
|
|
|
|
|
int index = 0;
|
|
|
|
|
while (true)
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
2022-03-20 19:27:50 +04:00
|
|
|
|
if (props[index++] == "Method")
|
2022-03-18 13:27:14 +04:00
|
|
|
|
break;
|
2022-03-20 19:27:50 +04:00
|
|
|
|
if (index == props.Length)
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
2022-03-20 19:27:50 +04:00
|
|
|
|
break;
|
2022-03-18 13:27:14 +04:00
|
|
|
|
}
|
2022-03-20 19:27:50 +04:00
|
|
|
|
}
|
|
|
|
|
var methodName = props[index].Split('[')?[0];
|
|
|
|
|
if (string.IsNullOrEmpty(methodName))
|
|
|
|
|
{
|
2022-03-18 13:27:14 +04:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-03-20 19:27:50 +04:00
|
|
|
|
var parameters = props[index].Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries)?[1].Split(',');
|
|
|
|
|
var objs = new object[parameters.Length];
|
|
|
|
|
for (int i = 0; i < parameters.Length; ++i)
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
2022-03-20 19:27:50 +04:00
|
|
|
|
var type = parameters[i].Split(':')[0];
|
|
|
|
|
switch (type)
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
2022-03-20 19:27:50 +04:00
|
|
|
|
case "Enum":
|
|
|
|
|
objs[i] = Enum.Parse(customAttribute.MethodParams[i], parameters[i].Split(':')[1]);
|
|
|
|
|
break;
|
2022-03-18 13:27:14 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-20 19:27:50 +04:00
|
|
|
|
value = typeFrom.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, value, objs);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
var bindingProperty = value.GetType().GetProperty(prop);
|
|
|
|
|
if (bindingProperty != null)
|
|
|
|
|
{
|
|
|
|
|
value = bindingProperty.GetValue(value);
|
|
|
|
|
if (value is null)
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-20 19:27:50 +04:00
|
|
|
|
else
|
2022-03-18 13:27:14 +04:00
|
|
|
|
{
|
2022-03-20 19:27:50 +04:00
|
|
|
|
value = null;
|
|
|
|
|
break;
|
2022-03-18 13:27:14 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-28 19:15:55 +04:00
|
|
|
|
}
|