Перейти к содержанию

Создание карточки-сателлита

Создание карточки-сателлита

Карточка-сателлит - это специальная карточка, которая прозрачно для пользователя сопровождает основную карточку, т.е. пользователь явно не создаёт и не удаляет сателлит, и даже не подозревает о его существовании. Например, карточка с настройками сотрудника, которая позволяет соотнести с каждым сотрудником его настройки рабочего места, при этом не изменяя внешний вид и структуру основной карточки сотрудника.

Сателлит даёт следующие преимущества:

  • Можно изменять связанные с карточкой данные, не изменяя версию карточки.

  • Можно выполнять параллельное изменение данных (например, при параллельном согласовании), не блокируя основную карточку.

  • Можно связать данные с типом карточки, не изменяя его структуру. Это позволяет иметь нестандартное API (такое, как ролевая модель), которое продолжит корректно взаимодействовать с основной карточкой.

  • Неизменность структуры основной карточки также обеспечивает бинарную совместимость этой карточки. Т.е. ранее удалённые или экспортированные карточки без сателлита по-прежнему можно будет восстановить.

Для карточки-сателлита необходимо обеспечить:

  • Создание по первому требованию со стороны расширений. Это может быть старт бизнес-процесса или явный запрос настроек сотрудника при старте приложения.

  • Загрузка по идентификатору основной карточки. Писатели расширений должны легко получить данные сателлита как на клиенте, так и на сервере, зная только идентификатор основной карточки.

  • Автоматическое удаление при удалении основной карточки.

  • Автоматический экспорт при экспорте основной карточки.

  • Автоматический импорт при импорте основной карточки.

  • Восстановление из корзины вместе с восстановлением основной карточки.

Для упрощения разработки сателлитов карточек в системе предусмотрен механизм универсальных сателлитов, который уже обеспечивает все вышеописанные требования к сателлитам, а также позволяет их расширять с помощью дополнительно реализованного обработчика сателлитов.

Универсальные сателлиты

Механизм универсальных сателлитов состоит из 3 основных объектов:

  • ISatelliteTypeRegistry - объект, в котором регистрируются новые типы сателлитов. Он реализован в платформе.

  • SatelliteTypeDescriptor - дескриптор типа сателлита. Содержит настройки типа сателлита. Создается отдельно для каждого типа сателлита.

  • ISatelliteHandler - обработчик сателлита, в котором реализуется дополнительная логика обработки сателлита. Может создаваться для как отдельно для каждого типа сателлита, так и в нескольких типах сателлита.

Дескриптор типа сателлита SatelliteTypeDescriptor имеет следующие свойства:

  • IsSingleton - данный флаг определяет, должен ли данный тип сателлита быть синглтоном по отношению к основной карточке или к заданию, если данный тип сателлита относится к заданию карточки. Когда для типа сателлита установлен этот флаг, а у карточки уже есть сателлит с данным типом, то при попытке создать новый сателлит будет возвращена ошибка.

  • IsDeferredStore - данный флаг определяет, будет ли сателлит автоматически сохранен в базе при его первой загрузке. Если флаг не установлен, то при попытке получить карточку сателлита, если сателлита данного типа еще нет, он будет автоматически создан и сохранен. Если флаг установлен - то только создан.

  • IsTaskSatellite - флаг определяет, отноится ли сателлит к самой карточке или к конкретному заданию карточки.

  • AllowGetFromClient - флаг определяет, доступна ли загрузка сателлита с клиента.

  • AllowDeleteFromClient - флаг определяет, доступно ли удаление сателлита с клиента.

  • LoadMainCardFiles - флаг определяет, что при загрузке данного сателлита к нему будут добавлены на чтение все файлы основной карточки. Обычно не устанавливается без флага AllowGetFromClient.

  • IgnoreStoreExtensions - флаг определяет, что для сателлита с данным типом не применяются стандартные расширения на сохранение для сателлитов.

  • IgnoreGetPrepare - флаг определяет, что при загрузке сателлита не будут производиться методы подготовки сателлита по основной карточке. Это означает, что будут проигнорирован флаг LoadMainCardFiles в настройках дескриптора, а также логика работы методов PrepareSatelliteForGetAsync и GetExternalFileSourcesAsync в хендлере данного типа сателлита.

  • CopySatelliteOnCardCopy - флаг определяет, должен ли сателлит копироваться вместе с основной карточкой.

  • HandlerType - тип обработчика, который будет использоваться в расширениях для данного типа сателлита. Методы, которые можно переопределить обработчике сателлита, описаны ниже.

Обработчик сателлита ISatelliteHandler имеет следующие методы, которые можно переопределить:

  • IsMainCardTypeAsync - метод для проверки, является ли тип основной карточки (для которой создается сателлит) типом, который может иметь данный сателлит.

  • GetExternalFileSourcesAsync - метод для получения списка пар “идентификатор карточки”-“идентификатор типа карточки”, файлы которых добавляются в данный сателлит при его загрузке. Логика данного метода игнорируется, если в дескрипторе типа сателлита установлен флаг IgnoreGetPrepare.

  • SetupSatelliteFileAsync - метод для фильтрации и подготовки карточек файлов, которые были добавлены из основной карточки (при наличии флага LoadMainCardFiles в дескрипторе типа сателлита) или из карточек, которые вернул метод GetExternalFileSourcesAsync. В данном методе можно отфильтровать файлы, которые не должны быть переданы в сателлит, или изменить свойства файлов.

  • IsMainCardFileAsync - метод для определения, является ли данный файл - файлом основной карточки. При сохранении карточки сателлита с файлом, если файл относится к основной карточке, файл будет добавлен к основной карточке, а не карточке сателлита. По умолчанию для всех файлов возвращает false.

  • PrepareMainCardFileToStoreAsync - метод для подготовки сохранения файла в основную карточку при сохранении карточки сателлита. Вызывается для тех файлов, для которых метод IsMainCardFileAsync вернул true.

  • PrepareSatelliteForGetAsync - метод для подготовки карточки сателлита при его загрузке. В нем можно производить заполнение виртуальных секций карточки сателлита с использованием основной карточки. Данный метод выполняется после добавления файлов из основной карточки/других карточек, поэтому в нем также можно отфильтровать данные файлы или измеить их свойства. Логика данного метода игнорируется, если в дескрипторе типа сателлита установлен флаг IgnoreGetPrepare.

  • PrepareSatelliteForBackupAsync - метод для подготовки карточки сателлита при удалении основной карточки в корзину.

  • PrepareSatelliteForExportAsync - метод для подготовки карточки сателлита при экспорте основной карточки.

  • PrepareSatelliteForCreateAsync - метод для подготовки карточки сателлита при ее создании.

  • CheckFileAccessAsync - метод для проверки доступа к содержимому файла, когда содержимое загружается из карточки сателлита.

  • CheckFileVersionsAccessAsync - метод для првоерки доступа к списку версий файла, когда список загружается из карточки сателлита.

  • PrepareSatelliteForImportAsync - метод для подготовки карточки сателлита при импорте основной карточки.

  • PrepareSatelliteForDeleteAsync - метод для подготовки карточки сателлита при удалении основной карточки.

  • PrepareSatelliteForRestoreAsync - метод для подготовки карточки сателлита при восстановлении основной карточки из корзины.

  • PrepareSatelliteForRepareAsync - метод для починки карточки сателлита, который вызывается при починке основной карточки.

Создание нового типа сателлита

Чтобы создать новый тип сателлита нужно:

  1. В свой тип карточки, который необходимо сделать сателлитом, добавить секцию Satellites вместе с колонками MainCard, Type и, если сателлит должен относится не к самой карточке, а к некому заданию, то также необходимо добавить колонку Task.

  2. Необходимо создать объект с классом SatelliteTypeDescriptor с указанием идентификатора необходимого типа карточки, а также задать необходимые свойства, определяющие поведение при работе сателлита:

    new SatelliteTypeDescriptor(DefaultCardTypes.KrSatelliteTypeID) { HandlerType = typeof(KrSatelliteHandler), IsSingleton = true, IgnoreGetPrepare = true, }

  3. В регистраторе в методе FinalizeRegistration необходимо зарезолвить объект ISatelliteTypeRegistry и зарегистрировать в нем через метод Register объект дескриптора типа сателлита, созданный в предыдущем пункте:

    var registry = this.UnityContainer.Resolve<ISatelliteTypeRegistry>(); registry.Register(new SatelliteTypeDescriptor(DefaultCardTypes.KrSatelliteTypeID) { HandlerType = typeof(KrSatelliteHandler), IsSingleton = true, IgnoreGetPrepare = true, });

    registry.Register(new SatelliteTypeDescriptor(DefaultCardTypes.KrSecondarySatelliteTypeID) { HandlerType = typeof(KrSecondarySatelliteHandler), IgnoreGetPrepare = true, });

  4. Если для типа сателлита необходимо реализовать дополнительное поведение, то нужно создать свой тип, который реализует интерфейс ISatelliteHandler, зарегистрировать его в Unity и указать данный тип в качестве значения для свойства HandlerType в объект дескриптора типа сателлита. Для удобства можно наследоваться от класса SatelliteHandlerBase:

    public sealed class WfSatelliteHandler : SatelliteHandlerBase { #region Fields

    private readonly IKrTypesCache krTypesCache;

    #endregion

    #region Constructors

    public WfSatelliteHandler(IKrTypesCache krTypesCache) { this.krTypesCache = krTypesCache; }

    #endregion

    #region Base Overrides

    public override ValueTask<bool> IsMainCardTypeAsync(CardType mainCardType, CancellationToken cancellationToken = default) { return WfHelper.TypeSupportsWorkflowAsync(this.krTypesCache, mainCardType, cancellationToken); }

    #endregion } ..... public override void RegisterUnity() { this.UnityContainer .RegisterType<WfSatelliteHandler>(new ContainerControlledLifetimeManager()) ; }

Автоматические сателлиты

В системе есть возможность создавать карточки сателлитов без использования каких-либо расширений.

Для этого достаточно в тип карточки добавить секцию Satellites вместе с колонками MainCard, Type. Система будет использовать данный тип карточки как сателлит с настройками, которые указаны в дескрипторе SatelliteTypeDescriptor.AutoSatelliteType.

Это позволяет легко сделать карточки-сателлиты без особой логики, или логикой, реализованной собственными расширениями, которые при этом автоматически будут экспортироваться, импортироваться, удаляться, удаляться в корзину и восстанавливаться вместе с основной карточкой.

Back to top