5d7503209a
Абстрактный базовый класс + два sealed-наследника вместо одного DTO с опциональными полями под обе категории — так специфичные для каждого вида напоминания поля не путаются с полями другого вида. Полиморфная сериализация System.Text.Json ([JsonPolymorphic]/[JsonDerivedType]) нужна, иначе список IReadOnlyList<ReminderDto> сериализовался бы только по общим полям базового класса.
41 lines
2.9 KiB
C#
41 lines
2.9 KiB
C#
using System.Text.Json.Serialization;
|
||
|
||
namespace Tnsu.ApprovalRoute.Application.Reminders;
|
||
|
||
/// <param name="Category">Вид напоминания — один на конкретный (sealed) наследник, см. их конструкторы.</param>
|
||
/// <param name="Url">Ссылка на заявку.</param>
|
||
/// <param name="RequestTypeId">Id типа заявки (RequestType).</param>
|
||
/// <param name="RequestTypeName">Название типа заявки — для читаемости в письме/таблице, без похода в БД.</param>
|
||
/// <param name="RequestId">Id заявки (TicketId строки списка согласования / Id строки списка данных).</param>
|
||
/// <param name="Status">Статус заявки/шага — из того списка, который читает конкретный вид напоминания.</param>
|
||
/// <param name="RequestUniqueCode">
|
||
/// Уникальный код заявки (колонка RequestUniqueCode списка данных) — null, если у
|
||
/// заявки его нет или строка данных не найдена.
|
||
/// </param>
|
||
/// <remarks>
|
||
/// Общая часть двух видов напоминаний — <see cref="ApprovalOverdueReminderDto"/> и
|
||
/// <see cref="ProbationEndingReminderDto"/>. У них разные поля-триггеры и разные
|
||
/// адресаты, общее — только то, что описано здесь (к какой заявке относится строка
|
||
/// и как её открыть).
|
||
///
|
||
/// [JsonPolymorphic]/[JsonDerivedType] — вместо того чтобы полагаться на
|
||
/// compile-time тип элемента (ReminderService всегда работает со списком именно
|
||
/// этого базового типа, см. IReadOnlyList<ReminderDto>), System.Text.Json без
|
||
/// этих атрибутов сериализовал бы только поля базового класса, теряя специфичные
|
||
/// для наследника (Email/HoursOverdue или ManagerEmail/CandidateEmail и т.д.).
|
||
/// Дискриминатор — отдельное системное поле "$type", а не Category: значение
|
||
/// Category читаемое (совпадает с именем enum-константы через уже подключенный
|
||
/// глобально JsonStringEnumConverter, см. Program.cs) и не привязано к деталям
|
||
/// сериализации.
|
||
/// </remarks>
|
||
[JsonPolymorphic]
|
||
[JsonDerivedType(typeof(ApprovalOverdueReminderDto), nameof(ReminderCategory.ApprovalOverdue))]
|
||
[JsonDerivedType(typeof(ProbationEndingReminderDto), nameof(ReminderCategory.ProbationEnding))]
|
||
public abstract record ReminderDto(
|
||
ReminderCategory Category,
|
||
string Url,
|
||
int RequestTypeId,
|
||
string RequestTypeName,
|
||
int RequestId,
|
||
string Status,
|
||
string? RequestUniqueCode); |