переделка работы мапера

This commit is contained in:
kotcheshir73 2022-03-18 13:27:14 +04:00
parent 6e2e10aa14
commit 1d3d35d106
10 changed files with 197 additions and 168 deletions

View File

@ -12,16 +12,19 @@ namespace CoreModels.ModelsSecurity
/// <summary> /// <summary>
/// Илентификатор роли /// Илентификатор роли
/// </summary> /// </summary>
[CheckRigthForMap]
Guid RoleId { get; } Guid RoleId { get; }
/// <summary> /// <summary>
/// Тип операции /// Тип операции
/// </summary> /// </summary>
[CheckRigthForMap]
AccessOperation AccessOperation { get; } AccessOperation AccessOperation { get; }
/// <summary> /// <summary>
/// Режим доступа /// Режим доступа
/// </summary> /// </summary>
[CheckRigthForMap]
AccessType AccessType { get; } AccessType AccessType { get; }
} }
} }

View File

@ -12,16 +12,19 @@ namespace CoreModels.ModelsSecurity
/// <summary> /// <summary>
/// Ключ настройки /// Ключ настройки
/// </summary> /// </summary>
[CheckRigthForMap]
string Key { get; } string Key { get; }
/// <summary> /// <summary>
/// Значение настройки /// Значение настройки
/// </summary> /// </summary>
[CheckRigthForMap]
string Value { get; } string Value { get; }
/// <summary> /// <summary>
/// Описание настройки /// Описание настройки
/// </summary> /// </summary>
[CheckRigthForMap]
string Description { get; } string Description { get; }
} }
} }

View File

@ -12,16 +12,20 @@ namespace CoreModels.ModelsSecurity
{ {
string UserName { get; } string UserName { get; }
[CheckRigthForMap]
string PasswordHash { get; } string PasswordHash { get; }
byte[] Avatar { get; } byte[] Avatar { get; }
DateTime? DateLastVisit { get; } DateTime? DateLastVisit { get; }
[CheckRigthForMap]
bool IsBanned { get; } bool IsBanned { get; }
[CheckRigthForMap]
DateTime? DateBanned { get; } DateTime? DateBanned { get; }
[CheckRigthForMap]
int CountAttempt { get; } int CountAttempt { get; }
} }
} }

View File

@ -12,8 +12,10 @@ namespace CoreModels.ModelsSecurity
[EntityDependency("User", "UserId", "К какой роли относится пользователь")] [EntityDependency("User", "UserId", "К какой роли относится пользователь")]
public interface IUserRoleModel : IId public interface IUserRoleModel : IId
{ {
[CheckRigthForMap]
Guid RoleId { get; } Guid RoleId { get; }
[CheckRigthForMap]
Guid UserId { get; } Guid UserId { get; }
} }
} }

View File

@ -0,0 +1,12 @@
using System;
namespace ModuleTools.Attributes
{
/// <summary>
/// Признак, гооврящий о том, что нужна проверка доступа к значению свойства при создании одного объекта на основе другого
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class CheckRigthForMapAttribute : Attribute
{
}
}

View File

@ -1,165 +1,182 @@
using ModuleTools.Attributes; using ModuleTools.Attributes;
using System; using System;
using System.Collections; using System.Collections;
using System.Linq;
using System.Reflection; using System.Reflection;
namespace ModuleTools.BusinessLogics namespace ModuleTools.BusinessLogics
{ {
/// <summary> /// <summary>
/// Маппер сущностей /// Маппер сущностей
/// </summary> /// </summary>
public class Mapper public class Mapper
{ {
/// <summary> /// <summary>
/// Преобразование из одного класса в другой /// Преобразование из одного класса в другой
/// </summary> /// </summary>
/// <typeparam name="From"></typeparam> /// <typeparam name="From"></typeparam>
/// <typeparam name="To"></typeparam> /// <typeparam name="To"></typeparam>
/// <param name="obj"></param> /// <param name="obj"></param>
/// <param name="haveRigth"></param> /// <param name="haveRigth"></param>
/// <returns></returns> /// <returns></returns>
public static To MapToClass<From, To>(From obj, bool haveRigth) where To : class => FillObject(obj, (To)Activator.CreateInstance(typeof(To)), haveRigth); public static To MapToClass<From, To>(From obj, bool haveRigth) where To : class => FillObject(obj, (To)Activator.CreateInstance(typeof(To)), haveRigth);
/// <summary> /// <summary>
/// Преобразование из одного класса в другой /// Преобразование из одного класса в другой
/// </summary> /// </summary>
/// <typeparam name="From"></typeparam> /// <typeparam name="From"></typeparam>
/// <typeparam name="To"></typeparam> /// <typeparam name="To"></typeparam>
/// <param name="obj"></param> /// <param name="obj"></param>
/// <param name="newObject"></param> /// <param name="newObject"></param>
/// <returns></returns> /// <returns></returns>
public static To MapToClass<From, To>(From obj, To newObject, bool haveRigth) where To : class => FillObject(obj, newObject, haveRigth); public static To MapToClass<From, To>(From obj, To newObject, bool haveRigth) where To : class => FillObject(obj, newObject, haveRigth);
/// <summary> /// <summary>
/// Заполнение объекта /// Заполнение объекта
/// </summary> /// </summary>
/// <typeparam name="From"></typeparam> /// <typeparam name="From"></typeparam>
/// <typeparam name="To"></typeparam> /// <typeparam name="To"></typeparam>
/// <param name="obj"></param> /// <param name="obj"></param>
/// <param name="newObject"></param> /// <param name="newObject"></param>
/// <param name="haveRigth"></param> /// <param name="haveRigth"></param>
/// <returns></returns> /// <returns></returns>
private static To FillObject<From, To>(From obj, To newObject, bool haveRigth) private static To FillObject<From, To>(From obj, To newObject, bool haveRigth)
where To : class where To : class
{ {
if (obj == null) if (obj == null)
{ {
return null; return null;
} }
if (newObject == null) if (newObject == null)
{ {
return null; return null;
} }
var typeFrom = typeof(From); var typeFrom = typeof(From);
var typeTo = typeof(To); var typeTo = typeof(To);
var properties = typeTo.GetProperties(); var properties = typeTo.GetProperties().Where(x => x.CanWrite);
foreach (var property in properties) foreach (var property in properties)
{ {
object value = obj; var checkRight = property.GetCustomAttribute<CheckRigthForMapAttribute>();
var customAttribute = property.GetCustomAttribute<MapConfigurationAttribute>(); if (!haveRigth && checkRight != null)
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); continue;
if (bindingProperty != null) }
{
property.SetValue(newObject, bindingProperty.GetValue(value));
}
}
}
return newObject; object value = obj;
} var customAttribute = property.GetCustomAttribute<MapConfigurationAttribute>();
} if (customAttribute != null)
{
if (!haveRigth && !customAttribute.AllowCopyWithoutRigth)
{
continue;
}
value = GetValueFromCustomAttribute(customAttribute, typeFrom, obj);
}
else
{
var bindingProperty = value.GetType().GetProperty(property.Name);
if (bindingProperty != null)
{
value = bindingProperty.GetValue(obj);
}
}
if (value is null)
{
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;
}
private static object GetValueFromCustomAttribute(MapConfigurationAttribute customAttribute, Type typeFrom, object obj)
{
object value = obj;
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);
}
}
return value;
}
}
} }

View File

@ -18,7 +18,6 @@ namespace SecurityBusinessLogic.ViewModels
public class AccessViewModel : ElementViewModel, IAccessModel public class AccessViewModel : ElementViewModel, IAccessModel
{ {
[ViewModelControlElementProperty("Роль", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = true, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlRoleList, SecurityWindowsDesktop")] [ViewModelControlElementProperty("Роль", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = true, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlRoleList, SecurityWindowsDesktop")]
[MapConfiguration("RoleId", AllowCopyWithoutRigth = false)]
public Guid RoleId { get; set; } public Guid RoleId { get; set; }
[ViewModelControlListProperty("Роль", ColumnWidth = 100)] [ViewModelControlListProperty("Роль", ColumnWidth = 100)]
@ -26,14 +25,12 @@ namespace SecurityBusinessLogic.ViewModels
public string RoleName { get; set; } public string RoleName { get; set; }
[ViewModelControlElementProperty("Операция", ControlType.ControlEnum, MustHaveValue = true)] [ViewModelControlElementProperty("Операция", ControlType.ControlEnum, MustHaveValue = true)]
[MapConfiguration("AccessOperation", AllowCopyWithoutRigth = false)]
public AccessOperation AccessOperation { get; set; } public AccessOperation AccessOperation { get; set; }
[ViewModelControlListProperty("Операция")] [ViewModelControlListProperty("Операция")]
public string AccessOperationTitle => AccessOperation.ToString("G"); public string AccessOperationTitle => AccessOperation.ToString("G");
[ViewModelControlElementProperty("Тип", ControlType.ControlEnum, MustHaveValue = true)] [ViewModelControlElementProperty("Тип", ControlType.ControlEnum, MustHaveValue = true)]
[MapConfiguration("AccessType", AllowCopyWithoutRigth = false)]
public AccessType AccessType { get; set; } public AccessType AccessType { get; set; }
[ViewModelControlListProperty("Тип", ColumnWidth = 150)] [ViewModelControlListProperty("Тип", ColumnWidth = 150)]

View File

@ -5,10 +5,10 @@ using ModuleTools.ViewModels;
namespace SecurityBusinessLogic.ViewModels namespace SecurityBusinessLogic.ViewModels
{ {
/// <summary> /// <summary>
/// Список общих настроек системы /// Список общих настроек системы
/// </summary> /// </summary>
public class EnviromentSettingListViewModel : ListViewModel<EnviromentSettingViewModel> { } public class EnviromentSettingListViewModel : ListViewModel<EnviromentSettingViewModel> { }
/// <summary> /// <summary>
/// Элемент общих настроек системы /// Элемент общих настроек системы
@ -18,17 +18,14 @@ namespace SecurityBusinessLogic.ViewModels
{ {
[ViewModelControlListProperty("Ключ")] [ViewModelControlListProperty("Ключ")]
[ViewModelControlElementProperty("Ключ", ControlType.ControlString, MustHaveValue = true, ReadOnly = true)] [ViewModelControlElementProperty("Ключ", ControlType.ControlString, MustHaveValue = true, ReadOnly = true)]
[MapConfiguration("Key", AllowCopyWithoutRigth = false)]
public string Key { get; set; } public string Key { get; set; }
[ViewModelControlListProperty("Значение")] [ViewModelControlListProperty("Значение")]
[ViewModelControlElementProperty("Значение", ControlType.ControlString, MustHaveValue = true)] [ViewModelControlElementProperty("Значение", ControlType.ControlString, MustHaveValue = true)]
[MapConfiguration("Value", AllowCopyWithoutRigth = false)]
public string Value { get; set; } public string Value { get; set; }
[ViewModelControlListProperty("Описание")] [ViewModelControlListProperty("Описание")]
[ViewModelControlElementProperty("Описание", ControlType.ControlText, Height = 200)] [ViewModelControlElementProperty("Описание", ControlType.ControlText, Height = 200)]
[MapConfiguration("Description", AllowCopyWithoutRigth = false)]
public string Description { get; set; } public string Description { get; set; }
} }
} }

View File

@ -18,7 +18,6 @@ namespace SecurityBusinessLogic.ViewModels
public class UserRoleViewModel : ElementViewModel, IUserRoleModel public class UserRoleViewModel : ElementViewModel, IUserRoleModel
{ {
[ViewModelControlElementProperty("Пользователь", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlUserList, SecurityWindowsDesktop")] [ViewModelControlElementProperty("Пользователь", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlUserList, SecurityWindowsDesktop")]
[MapConfiguration("UserId", AllowCopyWithoutRigth = false)]
public Guid UserId { get; set; } public Guid UserId { get; set; }
[ViewModelControlListProperty("Пользователь")] [ViewModelControlListProperty("Пользователь")]
@ -26,7 +25,6 @@ namespace SecurityBusinessLogic.ViewModels
public string UserName { get; set; } public string UserName { get; set; }
[ViewModelControlElementProperty("Роль", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlRoleList, SecurityWindowsDesktop")] [ViewModelControlElementProperty("Роль", ControlType.ControlGuid, MustHaveValue = true, ReadOnly = false, ControlTypeObject = "SecurityWindowsDesktop.EntityControls.ControlRoleList, SecurityWindowsDesktop")]
[MapConfiguration("RoleId", AllowCopyWithoutRigth = false)]
public Guid RoleId { get; set; } public Guid RoleId { get; set; }
[ViewModelControlListProperty("Роль")] [ViewModelControlListProperty("Роль")]

View File

@ -23,7 +23,6 @@ namespace SecurityBusinessLogic.ViewModels
[ViewModelControlElementProperty("Логин", ControlType.ControlString, MustHaveValue = true)] [ViewModelControlElementProperty("Логин", ControlType.ControlString, MustHaveValue = true)]
public string UserName { get; set; } public string UserName { get; set; }
[MapConfiguration("PasswordHash", AllowCopyWithoutRigth = false)]
public string PasswordHash { get; set; } public string PasswordHash { get; set; }
[ViewModelControlElementProperty("Фото", ControlType.ControlImage, Width = 200, Height = 200)] [ViewModelControlElementProperty("Фото", ControlType.ControlImage, Width = 200, Height = 200)]
@ -33,21 +32,18 @@ namespace SecurityBusinessLogic.ViewModels
public DateTime? DateLastVisit { get; set; } public DateTime? DateLastVisit { get; set; }
[ViewModelControlElementProperty("Заблокирован", ControlType.ControlBool, MustHaveValue = true)] [ViewModelControlElementProperty("Заблокирован", ControlType.ControlBool, MustHaveValue = true)]
[MapConfiguration("IsBanned", AllowCopyWithoutRigth = false)]
public bool IsBanned { get; set; } public bool IsBanned { get; set; }
[ViewModelControlListProperty("Блокир.", ColumnWidth = 80)] [ViewModelControlListProperty("Блокир.", ColumnWidth = 80)]
public string Banned => IsBanned ? "Да" : "Нет"; public string Banned => IsBanned ? "Да" : "Нет";
[ViewModelControlElementProperty("Дата блокировки", ControlType.ControlDateTime, ReadOnly = true)] [ViewModelControlElementProperty("Дата блокировки", ControlType.ControlDateTime, ReadOnly = true)]
[MapConfiguration("DateBanned", AllowCopyWithoutRigth = false)]
public DateTime? DateBanned { get; set; } public DateTime? DateBanned { get; set; }
[ViewModelControlListProperty("Дата Б.", ColumnWidth = 100)] [ViewModelControlListProperty("Дата Б.", ColumnWidth = 100)]
public string DateBannedTitle => DateBanned.HasValue ? DateBanned.Value.ToShortDateString() : string.Empty; public string DateBannedTitle => DateBanned.HasValue ? DateBanned.Value.ToShortDateString() : string.Empty;
[ViewModelControlElementProperty("Попытки входа", ControlType.ControlInt, ReadOnly = true)] [ViewModelControlElementProperty("Попытки входа", ControlType.ControlInt, ReadOnly = true)]
[MapConfiguration("CountAttempt", AllowCopyWithoutRigth = false)]
public int CountAttempt { get; set; } public int CountAttempt { get; set; }
} }
} }