This commit is contained in:
Александр Бабаев 2024-03-28 14:08:59 +03:00
parent 84d94a2463
commit f19ee998af
5 changed files with 166 additions and 347 deletions

View File

@ -9,7 +9,10 @@ namespace anbs_cp.Classes;
/*
История версий
Обновлено 2024.03.28
* Все поля Errors, Warnings и Infos объеденены в одно Messages
* В ActionStateMessage добавлен параметр, определяющий тип: MessageType
Обновлено 2024.03.26
* Все интерфейсы объеденины в один класс ActionStateMessage
* Интерфейс IActionState удалён
@ -27,48 +30,33 @@ namespace anbs_cp.Classes;
*/
/// <inheritdoc />
public class ActionState<T>: ISerializable
public class ActionState<T> (T? defaultValue = default): ISerializable
{
/// <summary>
/// Конструктор по умолчанию
/// </summary>
// ReSharper disable once MemberCanBeProtected.Global
public ActionState ()
{
Messages = [];
Value = default;
}
/// <summary>
/// Конструктор с указанием начального значения <see cref="Value"/>
/// </summary>
/// <param name="defaultValue">Начальное значение <see cref="Value"/></param>
public ActionState (T defaultValue)
{
Messages = [];
Value = defaultValue;
}
/// <summary>
/// Список информации
/// </summary>
public List<ActionStateMessage> Messages { get; }
// ReSharper disable once CollectionNeverQueried.Local
internal List<ActionStateMessage> Messages { get; } = [];
/// <summary>
/// Значение
/// </summary>
public T? Value { get; set; }
public T? Value { get; set; } = defaultValue;
/// <summary>
/// Метод для выбора всех значений для условия
/// </summary>
// ReSharper disable once StaticMemberInGenericType
public static readonly Func<ActionStateMessage, bool> SelectAll = _ => true;
#region Методы
#region Очистка
/// <summary>
/// Очищает список ошибок
/// </summary>
public void ClearErrors ()
{
Errors.Clear();
Errors.TrimExcess();
Clear(message => message.MessageType == EActionStateMessageType.Error);
}
/// <summary>
@ -76,8 +64,7 @@ public class ActionState<T>: ISerializable
/// </summary>
public void ClearWarnings ()
{
Warnings.Clear();
Warnings.TrimExcess();
Clear(message => message.MessageType == EActionStateMessageType.Warning);
}
/// <summary>
@ -85,18 +72,22 @@ public class ActionState<T>: ISerializable
/// </summary>
public void ClearInfo ()
{
Info.Clear();
Info.TrimExcess();
Clear(message => message.MessageType == EActionStateMessageType.Information);
}
/// <summary>
/// Очищает все списки
/// Очищает список по условию <paramref name="predicate"/>
/// </summary>
public void Clear ()
/// <param name="predicate">Условие выборки</param>
public void Clear (Func<ActionStateMessage, bool> predicate)
{
ClearInfo();
ClearWarnings();
ClearErrors();
// Получаю список элементов
IEnumerable<ActionStateMessage> list = Messages.Where(predicate);
// Для каждого элемента
foreach (ActionStateMessage actionStateMessage in list)
// - запускаю его удаление
Messages.Remove(actionStateMessage);
}
#endregion
@ -116,39 +107,21 @@ public class ActionState<T>: ISerializable
public void AddRange (IEnumerable<ActionStateMessage> messages) => Messages.AddRange(messages);
#endregion
#region Добавление ошибки
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="critical">Является ли ошибка критической</param>
public void AddError (bool critical = true)
{
//Создаю ошибку
ActionStateMessage error = new("", critical)
{
MessageType = EActionStateMessageType.Error
};
//Добавляю ошибку
Add(error);
}
public void AddError (bool critical = true) => Add(new(EActionStateMessageType.Error, critical));
/// <summary>
/// Добавление ошибки
/// </summary>
/// <param name="message">Сообщение об ошибке</param>
/// <param name="critical">Является ли ошибка критической</param>
public void AddError (string message, bool critical = true)
{
//Создаю ошибку
ActionStateMessage error = new(message, critical)
{
MessageType = EActionStateMessageType.Error
};
//Добавляю ошибку
Add(error);
}
public void AddError (string message, bool critical = true) =>
Add(new(EActionStateMessageType.Error, critical, message: message));
/// <summary>
/// Добавление ошибки
@ -156,73 +129,28 @@ public class ActionState<T>: ISerializable
/// <param name="errorObject">Объект ошибки</param>
/// <param name="message">Сообщение об ошибке</param>
/// /// <param name="critical">Является ли ошибка критической</param>
public void AddError (string errorObject, string message, bool critical = true)
{
//Создаю ошибку
ActionStateMessage error = new(errorObject, message, critical)
{
MessageType = EActionStateMessageType.Error
};
public void AddError (string errorObject, string message, bool critical = true) =>
Add(new(EActionStateMessageType.Error, critical, errorObject, message));
//Добавляю ошибку
Add(error);
}
#endregion
#region Добавление предупреждения
/// <summary>
/// Добавление предупреждения
/// </summary>
/// <param name="warning">Предупреждение</param>
public void AddWarning (ActionStateMessage warning) => Warnings.Add(warning);
/// <summary>
/// Добавление предупреждений
/// </summary>
/// <param name="warnings">Список предупреждений</param>
public void AddWarnings (IEnumerable<ActionStateMessage> warnings) => Warnings.AddRange(warnings);
/// <summary>
/// Добавление предупреждение
/// </summary>
/// <param name="message">Текст предупреждения</param>
/// <param name="warningObject">Объект предупреждения</param>
public void AddWarning (string message, string warningObject = "")
{
//Создаю предупреждение
ActionStateMessage warning = new(warningObject, message);
//Добавляю предупреждение
AddWarning(warning);
}
public void AddWarning (string message, string warningObject = "") =>
Add(new(EActionStateMessageType.Warning, message: message, obj: warningObject));
#endregion
#region Добавление информации
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="info">Информация</param>
public void AddInfo (ActionStateMessage info) => Info.Add(info);
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="infos">Список информации</param>
public void AddInfos (IEnumerable<ActionStateMessage> infos) => Info.AddRange(infos);
/// <summary>
/// Добавление информации
/// </summary>
/// <param name="message">Текст информации</param>
/// <param name="infoObject">Объект информации</param>
public void AddInfo (string message, string infoObject = "")
{
//Создаю информацию
ActionStateMessage info = new(infoObject, message);
//Добавляю информацию
AddInfo(info);
}
public void AddInfo (string message, string infoObject = "") => Add(new(message: message, obj: infoObject));
#endregion
#region Печать
@ -243,22 +171,20 @@ public class ActionState<T>: ISerializable
switch (area)
{
case EActionStatePrintArea.All:
list.AddRange(Errors);
list.AddRange(Warnings);
list.AddRange(Info);
list.AddRange(Messages);
break;
case EActionStatePrintArea.ErrorsAndWarnings:
list.AddRange(Errors);
list.AddRange(Warnings);
list.AddRange(Messages.Where(message =>
message.MessageType is EActionStateMessageType.Error or EActionStateMessageType.Warning));
break;
case EActionStatePrintArea.ErrorsOnly:
list.AddRange(Errors);
list.AddRange(Messages.Where(message => message.MessageType == EActionStateMessageType.Error));
break;
case EActionStatePrintArea.WarningsOnly:
list.AddRange(Warnings);
list.AddRange(Messages.Where(message => message.MessageType == EActionStateMessageType.Warning));
break;
case EActionStatePrintArea.InfosOnly:
list.AddRange(Info);
list.AddRange(Messages.Where(message => message.MessageType == EActionStateMessageType.Information));
break;
default:
throw new ArgumentOutOfRangeException(nameof(area), area, null);
@ -278,24 +204,24 @@ public class ActionState<T>: ISerializable
/// </summary>
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
/// <returns>Наличие ошибок</returns>
public bool HasErrors (bool ignoreNonCritical = false) =>
ignoreNonCritical ? Errors.Any(static error => error.IsCritical) : Errors.Any();
public bool HasErrors (bool ignoreNonCritical = false) => Messages.Any(message =>
message.MessageType == EActionStateMessageType.Error && (!ignoreNonCritical || !message.IsCritical));
/// <summary>
/// Проверяет, есть ли предупреждения
/// </summary>
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
/// <returns>Наличие предупреждений</returns>
public bool HasWarnings (bool ignoreInformWarning = false) => ignoreInformWarning
? Warnings.Any(static warning => warning.IsCritical)
: Warnings.Any();
public bool HasWarnings (bool ignoreInformWarning = false) => Messages.Any(message =>
message.MessageType == EActionStateMessageType.Warning && (!ignoreInformWarning || !message.IsCritical));
/// <summary>
/// Проверяет, есть ли сообщения
/// </summary>
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
/// <returns>Наличие сообщений</returns>
public bool HasInfo (bool ignoreStatus) => ignoreStatus ? Info.Any(static info => info.IsCritical) : Info.Any();
public bool HasInfo (bool ignoreStatus) => Messages.Any(message =>
message.MessageType == EActionStateMessageType.Information && (!ignoreStatus || !message.IsCritical));
/// <summary>
/// Успешно ли завершилось
@ -305,46 +231,45 @@ public class ActionState<T>: ISerializable
#endregion
#region Количество сообщений
/// <summary>
/// Количество сообщений, удовлеьворяющих условию <paramref name="predicate"/>
/// </summary>
/// <param name="predicate">Условие выборки</param>
/// <returns>Число сообщений</returns>
public int Count (Func<ActionStateMessage, bool> predicate) => Messages.Count(predicate);
/// <summary>
/// Количество ошибок
/// </summary>
/// <param name="ignoreNonCritical">Игнорировать не критические</param>
/// <returns>Количество ошибок</returns>
public int ErrorsCount (bool ignoreNonCritical = false) =>
ignoreNonCritical ? Errors.Count(static error => error.IsCritical) : Errors.Count;
public int ErrorsCount (bool ignoreNonCritical = false) => Count(message =>
message.MessageType == EActionStateMessageType.Error && (!ignoreNonCritical || !message.IsCritical));
/// <summary>
/// Количество предупреждений
/// </summary>
/// <param name="ignoreInformWarning">Игнорировать информационные предупреждения</param>
/// <returns>Количество предупреждений</returns>
public int WarningsCount (bool ignoreInformWarning = false) => ignoreInformWarning
? Warnings.Count(static warning => warning.IsCritical)
: Warnings.Count;
public int WarningsCount (bool ignoreInformWarning = false) => Count(message =>
message.MessageType == EActionStateMessageType.Warning && (!ignoreInformWarning || !message.IsCritical));
/// <summary>
/// Количество информационных сообщений
/// </summary>
/// <param name="ignoreStatus">Игнорировать статусные сообщения</param>
/// <returns>Количество информационных сообщений</returns>
public int InfoCount (bool ignoreStatus) => ignoreStatus
? Info.Count(static info => info.IsCritical)
: Info.Count;
public int InfoCount (bool ignoreStatus) => Count(message =>
message.MessageType == EActionStateMessageType.Information && (!ignoreStatus || !message.IsCritical));
#endregion
#region Добавление другого состояния
/// <summary>
/// Добавляет другое состояние (например, результат другого действия, который возвращает <see cref="ActionState"/>).
/// </summary>
/// <typeparam name="T">Тип параметра</typeparam>
/// <param name="state">Запись состояния</param>
public void AddState (ActionState<T> state)
{
AddErrors(state.Errors);
AddWarnings(state.Warnings);
AddInfos(state.Info);
}
public void AddState (ActionState<T> state) => AddRange(state.Messages);
#endregion
#endregion
@ -355,20 +280,10 @@ public class ActionState<T>: ISerializable
// Создаю модель
ActionStateSerializable serializableModel = new();
// Для каждого информационного сообщения
foreach (ActionStateMessage info in Info)
// Для каждого сообщения
foreach (ActionStateMessage message in Messages)
// - добавляю в модель
serializableModel.Info.Add(info.Serialize());
// Для каждого предупреждения
foreach (ActionStateMessage warning in Warnings)
// - добавляю в модель
serializableModel.Info.Add(warning.Serialize());
// Для каждой ошибки
foreach (ActionStateMessage error in Errors)
// - добавляю в модель
serializableModel.Info.Add(error.Serialize());
serializableModel.Messages.Add(message.Serialize());
// Создаю модель значения
ActionStateSerializableValue value = new();
@ -397,37 +312,17 @@ public class ActionState<T>: ISerializable
ActionStateSerializableValue value = new();
// Очищаю списки
Info.Clear();
Warnings.Clear();
Errors.Clear();
Clear(SelectAll);
// Для каждого информационного сообщения
foreach (string infoString in itemSerializable.Info)
// Для каждого сообщения
foreach (string messageString in itemSerializable.Messages)
{
// - создаю сообщение
ActionStateMessage info = new();
ActionStateMessage message = new();
// - десериализую в него данные из модели
info.Deserialize(infoString);
message.Deserialize(messageString);
// - добавляю в список
Info.Add(info);
}
foreach (string warningString in itemSerializable.Warnings)
{
// - создаю сообщение
ActionStateMessage warning = new();
// - десериализую в него данные из модели
warning.Deserialize(warningString);
// - добавляю в список
Info.Add(warning);
}
foreach (string errorString in itemSerializable.Errors)
{
// - создаю сообщение
ActionStateMessage error = new();
// - десериализую в него данные из модели
error.Deserialize(errorString);
// - добавляю в список
Info.Add(error);
Add(message);
}
// Десериализую данные значения из модели

View File

@ -9,143 +9,107 @@ namespace anbs_cp.Classes;
/// <summary>
/// Класс сообщения состояния
/// </summary>
public sealed class ActionStateMessage: ISerializable
public sealed class ActionStateMessage (
EActionStateMessageType type = EActionStateMessageType.Information,
bool isCritical = false,
string obj = "",
string message = ""): ISerializable
{
#region Свойства
/// <summary>
/// Тип сообщения
/// </summary>
public EActionStateMessageType MessageType { get; set; } = EActionStateMessageType.Information;
#region Свойства
/// <summary>
/// Тип сообщения
/// </summary>
public EActionStateMessageType MessageType { get; set; } = type;
/// <summary>
/// Критичность сообщения
/// </summary>
public bool IsCritical { get; set; }
/// <summary>
/// Критичность сообщения
/// </summary>
public bool IsCritical { get; set; } = isCritical;
/// <summary>
/// Объект сообщения
/// </summary>
public string Object { get; set; }
/// <summary>
/// Объект сообщения
/// </summary>
public string Object { get; set; } = obj;
/// <summary>
/// Текст сообщения
/// </summary>
public string Message { get; set; }
/// <summary>
/// Текст сообщения
/// </summary>
public string Message { get; set; } = message;
#endregion
#endregion
#region Конструкторы
#region Методы
/// <summary>
/// Конструктор по умолчанию
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
public ActionStateMessage ()
{
IsCritical = true;
Object = "Not Implemented";
Message = "Not Implemented";
}
/// <summary>
/// Вывод сообщения
/// </summary>
/// <param name="format">Строка-форматирование (например, «[{0}] - {1}»)</param>
/// <returns>Отформатированную строка</returns>
public string PrintMessage (string format) => string.Format(format, Object, Message);
/// <summary>
/// Конструктор с 2 параметрами
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="isCritical">Критичность сообщения</param>
public ActionStateMessage (string message, bool isCritical = true)
{
IsCritical = isCritical;
Object = "";
Message = message;
}
/// <summary>
/// Конструктор с 3 параметрами
/// </summary>
/// <param name="eObject">Объект сообщения</param>
/// <param name="message">Сообщение</param>
/// <param name="isCritical">Критичность сообщения</param>
public ActionStateMessage (string eObject, string message, bool isCritical = true)
{
IsCritical = isCritical;
Object = eObject;
Message = message;
}
#endregion
#region Методы
/// <summary>
/// Вывод сообщения
/// </summary>
/// <param name="format">Строка-форматирование (например, «[{0}] - {1}»)</param>
/// <returns>Отформатированную строка</returns>
public string PrintMessage (string format) => string.Format(format, Object, Message);
/// <summary>
/// Устанавливает объект
/// </summary>
/// <param name="obj">Объект</param>
/// <typeparam name="T">Тип объекта</typeparam>
public void SetObject<T> (T obj)
{
// Если объект реализует интерфейс ISerializable
if (obj is ISerializable serializable)
/// <summary>
/// Устанавливает объект
/// </summary>
/// <param name="obj">Объект</param>
/// <typeparam name="T">Тип объекта</typeparam>
public void SetObject<T> (T obj)
{
// - то сериализуем его методами интерфейса
Object = serializable.Serialize();
// - и прерываем
return;
// Если объект реализует интерфейс ISerializable
if (obj is ISerializable serializable)
{
// - то сериализуем его методами интерфейса
Object = serializable.Serialize();
// - и прерываем
return;
}
// Сериализуем объект с помощью NewtonsoftJson
Object = new NewtonsoftJsonSerializer().Serialize(obj);
}
// Сериализуем объект с помощью NewtonsoftJson
Object = new NewtonsoftJsonSerializer().Serialize(obj);
}
/// <summary>
/// Получает объект
/// </summary>
/// <typeparam name="T">Класс объекта</typeparam>
/// <returns>Объект или null</returns>
public T? GetObject<T> () => new NewtonsoftJsonSerializer().Deserialize<T>(Object);
/// <summary>
/// Получает объект
/// </summary>
/// <typeparam name="T">Класс объекта</typeparam>
/// <returns>Объект или null</returns>
public T? GetObject<T> () => new NewtonsoftJsonSerializer().Deserialize<T>(Object);
/// <summary>
/// Получает объект
/// </summary>
/// <typeparam name="T">Класс объекта, реализующий интерфейс ISerializable</typeparam>
/// <returns>Объект</returns>
public T GetSerializedObject<T> () where T : ISerializable, new()
{
// Создаём результирующую модель
T model = new();
/// <summary>
/// Получает объект
/// </summary>
/// <typeparam name="T">Класс объекта, реализующий интерфейс ISerializable</typeparam>
/// <returns>Объект</returns>
public T GetSerializedObject<T> () where T : ISerializable, new()
{
// Создаём результирующую модель
T model = new();
// Десериализуем её методами интерфейса ISerializable
model.Deserialize(Object);
// Десериализуем её методами интерфейса ISerializable
model.Deserialize(Object);
// Возвращаем модель
return model;
}
// Возвращаем модель
return model;
}
#endregion
#endregion
#region Реализация интерфейса ISerializable
#region Реализация интерфейса ISerializable
/// <inheritdoc />
public string Serialize () => new NewtonsoftJsonSerializer().Serialize(this);
/// <inheritdoc />
public string Serialize () => new NewtonsoftJsonSerializer().Serialize(this);
/// <inheritdoc />
public void Deserialize (string json)
{
// Десериализую строку
ActionStateMessage item = new NewtonsoftJsonSerializer().Deserialize<ActionStateMessage>(json) ?? new();
/// <inheritdoc />
public void Deserialize (string json)
{
// Десериализую строку
ActionStateMessage item = new NewtonsoftJsonSerializer().Deserialize<ActionStateMessage>(json) ?? new();
// Передаю параметры
MessageType = item.MessageType;
IsCritical = item.IsCritical;
Object = item.Object;
Message = item.Message;
}
// Передаю параметры
MessageType = item.MessageType;
IsCritical = item.IsCritical;
Object = item.Object;
Message = item.Message;
}
#endregion
#endregion
}

View File

@ -7,19 +7,9 @@ namespace anbs_cp.Classes;
public class ActionStateSerializable
{
/// <summary>
/// Список информации
/// Список всех сообщений
/// </summary>
public List<string> Info { get; } = [];
/// <summary>
/// Список предупреждений
/// </summary>
public List<string> Warnings { get; } = [];
/// <summary>
/// Список ошибок
/// </summary>
public List<string> Errors { get; } = [];
public List<string> Messages { get; } = [];
/// <summary>
/// Значение

View File

@ -31,20 +31,10 @@ public sealed class ActionStateSerialized<T>: ActionState<T> where T : ISerializ
// Создаю модель
ActionStateSerializable serializableModel = new();
// Для каждого информационного сообщения
foreach (ActionStateMessage info in Info)
// Для каждого сообщения
foreach (ActionStateMessage message in Messages)
// - добавляю в модель
serializableModel.Info.Add(info.Serialize());
// Для каждого предупреждения
foreach (ActionStateMessage warning in Warnings)
// - добавляю в модель
serializableModel.Info.Add(warning.Serialize());
// Для каждой ошибки
foreach (ActionStateMessage error in Errors)
// - добавляю в модель
serializableModel.Info.Add(error.Serialize());
serializableModel.Messages.Add(message.Serialize());
// Создаю модель значения
ActionStateSerializableValue value = new();
@ -73,37 +63,17 @@ public sealed class ActionStateSerialized<T>: ActionState<T> where T : ISerializ
ActionStateSerializableValue value = new();
// Очищаю списки
Info.Clear();
Warnings.Clear();
Errors.Clear();
Clear(SelectAll);
// Для каждого информационного сообщения
foreach (string infoString in itemSerializable.Info)
// Для каждого сообщения
foreach (string messageString in itemSerializable.Messages)
{
// - создаю сообщение
ActionStateMessage info = new();
ActionStateMessage message = new();
// - десериализую в него данные из модели
info.Deserialize(infoString);
message.Deserialize(messageString);
// - добавляю в список
Info.Add(info);
}
foreach (string warningString in itemSerializable.Warnings)
{
// - создаю сообщение
ActionStateMessage warning = new();
// - десериализую в него данные из модели
warning.Deserialize(warningString);
// - добавляю в список
Info.Add(warning);
}
foreach (string errorString in itemSerializable.Errors)
{
// - создаю сообщение
ActionStateMessage error = new();
// - десериализую в него данные из модели
error.Deserialize(errorString);
// - добавляю в список
Info.Add(error);
Add(message);
}
// Десериализую данные значения из модели

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Version>2024.3.27.2</Version>
<Version>2024.3.28</Version>
<Authors>Александр Бабаев</Authors>
<Product>Набор компонентов ANB Software</Product>
<Description>Библиотека полезных методов языка C#</Description>