Билдер для сущностей, что б красивее отображались
This commit is contained in:
@@ -16,15 +16,6 @@ public class EntitySerializer
|
||||
public List<FieldGroup> Groups { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Группа полей.
|
||||
/// </summary>
|
||||
public class FieldGroup
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public List<FieldInfo> Fields { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Информация о поле.
|
||||
/// </summary>
|
||||
@@ -49,21 +40,21 @@ public class EntitySerializer
|
||||
{
|
||||
SerializationResult result = new();
|
||||
|
||||
// Группа для основных полей Entity
|
||||
FieldGroup entityGroup = new() { Name = "Основные поля" };
|
||||
AddFieldsToGroup(entityGroup, fullEntity.Entity);
|
||||
result.Groups.Add(entityGroup);
|
||||
//// Группа для основных полей Entity
|
||||
//FieldGroup entityGroup = new() { Name = "Основные поля" };
|
||||
//AddFieldsToGroup(entityGroup, fullEntity.Entity);
|
||||
//result.Groups.Add(entityGroup);
|
||||
|
||||
// Группа для полей IEntity (SubEntity)
|
||||
if (fullEntity.SubEntity != null)
|
||||
{
|
||||
FieldGroup subEntityGroup = new()
|
||||
{
|
||||
Name = "Поля " + fullEntity.SubEntity.GetType().Name,
|
||||
};
|
||||
AddFieldsToGroup(subEntityGroup, fullEntity.SubEntity);
|
||||
result.Groups.Add(subEntityGroup);
|
||||
}
|
||||
//// Группа для полей IEntity (SubEntity)
|
||||
//if (fullEntity.SubEntity != null)
|
||||
//{
|
||||
// FieldGroup subEntityGroup = new()
|
||||
// {
|
||||
// Name = "Поля " + fullEntity.SubEntity.GetType().Name,
|
||||
// };
|
||||
// AddFieldsToGroup(subEntityGroup, fullEntity.SubEntity);
|
||||
// result.Groups.Add(subEntityGroup);
|
||||
//}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -71,25 +62,25 @@ public class EntitySerializer
|
||||
/// <summary>
|
||||
/// Добавить поля объекта в группу.
|
||||
/// </summary>
|
||||
private void AddFieldsToGroup(FieldGroup group, object obj)
|
||||
{
|
||||
Type type = obj.GetType();
|
||||
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
//private void AddFieldsToGroup(FieldGroup group, object obj)
|
||||
//{
|
||||
// Type type = obj.GetType();
|
||||
// PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
foreach (PropertyInfo property in properties)
|
||||
{
|
||||
// Пропускаем навигационные свойства Entity
|
||||
if (property.Name == "Entity")
|
||||
continue;
|
||||
// foreach (PropertyInfo property in properties)
|
||||
// {
|
||||
// // Пропускаем навигационные свойства Entity
|
||||
// if (property.Name == "Entity")
|
||||
// continue;
|
||||
|
||||
object? value = property.GetValue(obj);
|
||||
FieldInfo fieldInfo = CreateFieldInfo(property, value);
|
||||
group.Fields.Add(fieldInfo);
|
||||
}
|
||||
}
|
||||
// object? value = property.GetValue(obj);
|
||||
// FieldBuilderDefinition fieldInfo = CreateFieldInfo(property, value);
|
||||
// group.Fields.Add(fieldInfo);
|
||||
// }
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Создать FieldInfo для свойства.
|
||||
/// Создать FieldBuilderDefinition для свойства.
|
||||
/// </summary>
|
||||
/// <param name="property">Поле класса.</param>
|
||||
/// <param name="value">Значение поля.</param>
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pf2e.Web.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Построитель сериализации для типа T.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Тип сущности для сериализации.</typeparam>
|
||||
public class SerializationBuilder<T>
|
||||
where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Список групп полей.
|
||||
/// </summary>
|
||||
public List<FieldGroup> Groups { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Форматтер полей сущности.
|
||||
/// </summary>
|
||||
protected EntityFieldFormatter FieldFormatter { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет группу полей в построитель сериализации.
|
||||
/// </summary>
|
||||
/// <param name="name">Название группы.</param>
|
||||
/// <param name="configure">Делегат для настройки группы полей.</param>
|
||||
/// <returns>Текущий экземпляр построителя.</returns>
|
||||
public SerializationBuilder<T> AddGroup(string name, Action<FieldGroupBuilder<T>> configure)
|
||||
{
|
||||
FieldGroupBuilder<T> groupBuilder = new(name);
|
||||
configure(groupBuilder);
|
||||
Groups.Add(groupBuilder.Build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет группу полей в построитель сериализации с названием типа.
|
||||
/// </summary>
|
||||
/// <param name="configure">Делегат для настройки группы полей.</param>
|
||||
/// <returns>Текущий экземпляр построителя.</returns>
|
||||
public SerializationBuilder<T> AddGroup(Action<FieldGroupBuilder<T>> configure)
|
||||
{
|
||||
return AddGroup(typeof(T).Name, configure);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Построитель группы полей для типа TField.
|
||||
/// </summary>
|
||||
/// <typeparam name="TField">Тип сущности для группы полей.</typeparam>
|
||||
public class FieldGroupBuilder<TField>(string name)
|
||||
where TField : class
|
||||
{
|
||||
private readonly FieldGroup _group = new() { Name = name };
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет поле в группу.
|
||||
/// </summary>
|
||||
/// <param name="fieldExpression">Лямбда-выражение для получения поля.</param>
|
||||
/// <returns>Текущий экземпляр построителя группы полей.</returns>
|
||||
public FieldGroupBuilder<TField> AddField(Expression<Func<TField, object>> fieldExpression)
|
||||
{
|
||||
// Получаем информацию о свойстве из выражения
|
||||
MemberExpression? memberExpression = GetMemberExpression(fieldExpression.Body);
|
||||
if (memberExpression == null)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Выражение должно быть доступом к свойству",
|
||||
nameof(fieldExpression)
|
||||
);
|
||||
}
|
||||
|
||||
PropertyInfo propertyInfo = (PropertyInfo)memberExpression.Member;
|
||||
string fieldName = propertyInfo.Name;
|
||||
Type fieldType = propertyInfo.PropertyType;
|
||||
|
||||
_group.Fields.Add(new() { Name = fieldName, Type = fieldType });
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает форматтер значения для последнего добавленного поля.
|
||||
/// </summary>
|
||||
/// <param name="valueFormatter">Функция форматирования значения.</param>
|
||||
/// <returns>Текущий экземпляр построителя группы полей.</returns>
|
||||
public FieldGroupBuilder<TField> SetValueFormatter(Func<object, string> valueFormatter)
|
||||
{
|
||||
_group.Fields.Last().ValueFormatter = valueFormatter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Строит группу полей.
|
||||
/// </summary>
|
||||
/// <returns>Готовая группа полей.</returns>
|
||||
public FieldGroup Build() => _group;
|
||||
|
||||
/// <summary>
|
||||
/// Получает MemberExpression из тела лямбда-выражения.
|
||||
/// </summary>
|
||||
/// <param name="expression">Тело выражения.</param>
|
||||
/// <returns>MemberExpression или null, если не удалось получить.</returns>
|
||||
private static MemberExpression? GetMemberExpression(Expression expression)
|
||||
{
|
||||
return expression switch
|
||||
{
|
||||
MemberExpression memberExpression => memberExpression,
|
||||
UnaryExpression { NodeType: ExpressionType.Convert } unaryExpression =>
|
||||
unaryExpression.Operand as MemberExpression,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Группа полей.
|
||||
/// </summary>
|
||||
public class FieldGroup
|
||||
{
|
||||
/// <summary>
|
||||
/// Название группы.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Список полей в группе.
|
||||
/// </summary>
|
||||
public List<FieldBuilderDefinition> Fields { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Информация о поле.
|
||||
/// </summary>
|
||||
public class FieldBuilderDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Название поля.
|
||||
/// </summary>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Тип поля.
|
||||
/// </summary>
|
||||
public required Type Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Форматтер значения поля.
|
||||
/// </summary>
|
||||
public Func<object, string>? ValueFormatter { get; set; } = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user