using ModuleTools.Attributes; using System; using System.Collections; using System.Reflection; namespace ModuleTools.BusinessLogics { /// /// Маппер сущностей /// public class Mapper { /// /// Преобразование из одного класса в другой /// /// /// /// /// /// public static To MapToClass(From obj, bool haveRigth) where To : class => FillObject(obj, (To)Activator.CreateInstance(typeof(To)), haveRigth); /// /// Преобразование из одного класса в другой /// /// /// /// /// /// public static To MapToClass(From obj, To newObject, bool haveRigth) where To : class => FillObject(obj, newObject, haveRigth); /// /// Заполнение объекта /// /// /// /// /// /// /// private static To FillObject(From obj, To newObject, bool haveRigth) where To : class { if (obj == null) { return null; } if (newObject == null) { return null; } var typeFrom = typeof(From); var typeTo = typeof(To); var properties = typeTo.GetProperties(); foreach (var property in properties) { object value = obj; var customAttribute = property.GetCustomAttribute(); if (customAttribute != null) { if (customAttribute.IsDifficle) { var props = customAttribute.PropertyNameFromModel.Split('.'); foreach (var prop in props) { if (prop == "ToString") { value = value.ToString(); break; } else if (prop == "Count") { value = (value as ICollection)?.Count; break; } else if (prop == "Method") { int index = 0; while (true) { if (props[index++] == "Method") break; if (index == props.Length) { break; } } var methodName = props[index].Split('[')?[0]; if (string.IsNullOrEmpty(methodName)) { break; } 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) { var type = parameters[i].Split(':')[0]; switch(type) { case "Enum": objs[i] = (int)Enum.Parse(customAttribute.MethodParams[i], parameters[i].Split(':')[1]); break; } } 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) { break; } } else { value = null; break; } } } else { if (customAttribute.PropertyNameFromModel == "ToString") { value = value.ToString(); } var bindingProperty = typeFrom.GetProperty(customAttribute.PropertyNameFromModel); if (bindingProperty != null) { value = bindingProperty.GetValue(obj); } } if ((haveRigth && !customAttribute.AllowCopyWithoutRigth) || customAttribute.AllowCopyWithoutRigth) { if (property.PropertyType.Name.StartsWith("Nullable")) { if (Nullable.GetUnderlyingType(property.PropertyType).IsEnum) { property.SetValue(newObject, Enum.Parse(Nullable.GetUnderlyingType(property.PropertyType), value.ToString())); continue; } } property.SetValue(newObject, value); } } else { var bindingProperty = value.GetType().GetProperty(property.Name); if (bindingProperty != null) { property.SetValue(newObject, bindingProperty.GetValue(value)); } } } return newObject; } } }