Общие сведения
Надёжность и безопасность
Покупка лицензии
Начало работы
Роли в системе
Проекты
Концепции
Компоненты
Инструкции
Задачи
Финансы
Ресурсы
Таймшиты
Клиенты
Вики
Затраты
Отчёты и аналитика
FAQ
Типы отчётов
Использование отчётов
Группировка данных источника
Группировка данных в отчёте
Типы виджетов
Общие отчёты и шаблоны
Настройка отчёта
Экспорт отчётов
Пользовательские настройки отчёта
Вычисляемые поля
Выражения вычисляемых полей
Особые колонки отчётов с временными рядами
Использование панелей мониторинга
Публикация панелей
Фильтры источников данных
Настройка и администрирование
Типовой порядок настройки системы
On-premises
API
История изменений
Термины и определения

IEntityTypeCustomHooks<TEntity>

Обновлено: 13.03.2026

IEntityTypeCustomHooks<TEntity> — интерфейс для реализации пользовательской логики обработки операций над сущностью.

Реализация интерфейса позволяет перехватывать ключевые этапы работы с сущностью:

  • операции CRUD (создание, обновление, удаление);
  • переходы жизненного цикла;
  • запуск workflow.

Методы интерфейса система вызывает автоматически в нужные моменты выполнения операции.

Назначение

Обработчики расширяют стандартную логику платформы.

Типичные сценарии использования:

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

Общая структура интерфейса

public interface IEntityTypeCustomHooks<in TEntity>
    where TEntity : class, IEntity
{
    // CRUD операции
    Task BeforeUpsert(CustomHooksContext context, TEntity detachedEntity);
    Task BeforeDelete(CustomHooksContext context, TEntity detachedEntity);
    Task AfterUpsert(CustomHooksContext context, TEntity contextEntity, TEntity detachedEntity);
    Task AfterDelete(CustomHooksContext context, TEntity contextEntity);

    // Жизненный цикл
    Task BeforeSetState(CustomHooksContext context, TEntity entity, Guid oldStateId, Guid newStateId);
    Task AfterSetState(CustomHooksContext context, TEntity entity, Guid oldStateId, Guid newStateId);

    // Workflow
    Task BeforeStartWorkflow(CustomHooksContext context, TEntity contextEntity);
}

Хуки операций с сущностью

Эти методы вызываются при выполнении CRUD-операций через сервис сущностей.

Метод Когда вызывается Назначение
BeforeUpsert До вставки или обновления сущности Проверки, изменение данных перед сохранением
AfterUpsert После вставки или обновления Бизнес-логика, интеграции
BeforeDelete До удаления сущности Проверка возможности удаления
AfterDelete После удаления Очистка связанных данных, интеграции

BeforeUpsert

Task BeforeUpsert(CustomHooksContext context, TEntity detachedEntity);

Вызывается до сохранения сущности. Метод срабатывает для операций Insert и Update.

Параметры:

  • context — контекст выполнения обработчика;
  • detachedEntity — сущность, переданная пользователем (не привязана к DbContext).

Типичные сценарии:

  • проверка данных;
  • заполнение значений по умолчанию;
  • нормализация данных.

AfterUpsert

Task AfterUpsert(CustomHooksContext context, TEntity contextEntity, TEntity detachedEntity);

Вызывается после сохранения сущности.

Параметры:

  • context — контекст выполнения обработчика;
  • contextEntity — сущность из текущего DbContext;
  • detachedEntity — исходная сущность из запроса.

Типичные сценарии:

  • запуск интеграций;
  • создание связанных объектов;
  • отправка уведомлений.

BeforeDelete

Task BeforeDelete(CustomHooksContext context, TEntity detachedEntity);

Вызывается перед удалением сущности.

Параметры:

  • context — контекст выполнения;
  • detachedEntity — сущность, переданная для удаления.

Типичные сценарии:

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

AfterDelete

Task AfterDelete(CustomHooksContext context, TEntity contextEntity);

Вызывается после удаления сущности.

Параметры:

  • context — контекст выполнения;
  • contextEntity — удалённая сущность.

Типичные сценарии:

  • удаление связанных данных;
  • уведомления;
  • интеграции.

Хуки жизненного цикла

Методы вызываются при изменении состояния сущности, поддерживающей жизненный цикл (IStatedEntity).

Метод Когда вызывается
BeforeSetState До изменения состояния
AfterSetState После изменения состояния

BeforeSetState

Task BeforeSetState(
    CustomHooksContext context,
    TEntity entity,
    Guid oldStateId,
    Guid newStateId
);

Вызывается перед изменением состояния.

Параметры:

  • entity — сущность, для которой выполняется переход;
  • oldStateId — текущее состояние;
  • newStateId — новое состояние.

Типичные сценарии:

  • проверка допустимости перехода;
  • логирование изменений.

AfterSetState

Task AfterSetState(
    CustomHooksContext context,
    TEntity entity,
    Guid oldStateId,
    Guid newStateId
);

Вызывается после изменения состояния.

Типичные сценарии:

  • запуск интеграций;
  • уведомление пользователей;
  • создание задач.

Хук запуска workflow

BeforeStartWorkflow

Task BeforeStartWorkflow(CustomHooksContext context, TEntity contextEntity);

Вызывается перед запуском workflow для сущности.

Параметры:

  • context — контекст выполнения;
  • contextEntity — сущность из текущего DbContext.

Типичные сценарии:

  • подготовка данных для workflow;
  • проверки перед запуском процесса;
  • логирование.

Параметры методов

context

CustomHooksContext — контекст выполнения динамического кода. Предоставляет доступ к API системы:

  • сервисы сущностей;
  • сервис жизненного цикла;
  • HTTP-клиент;
  • сервис уведомлений;
  • логирование.

detachedEntity

Сущность, полученная из запроса пользователя. Особенности:

  • не привязана к DbContext;
  • содержит данные, переданные клиентом.

contextEntity

Сущность, загруженная из базы данных и отслеживаемая текущим DbContext. Используется для:

  • доступа к актуальному состоянию данных;
  • выполнения изменений в рамках текущей транзакции.

Пример реализации

public class CustomHooks : IEntityTypeCustomHooks<Project>
{
    public async Task BeforeUpsert(
        CustomHooksContext context,
        Project detachedEntity)
    {
        if (string.IsNullOrWhiteSpace(detachedEntity.Name))
            await context.Log("Имя проекта не задано", DynamicCodeLogLevel.Error);
    }

    public async Task AfterUpsert(
        CustomHooksContext context,
        Project contextEntity,
        Project detachedEntity)
    {
        await context.Log($"Проект сохранён: {contextEntity.Id}");
    }

    public async Task BeforeSetState(
        CustomHooksContext context,
        Project entity,
        Guid oldStateId,
        Guid newStateId)
    {
        await context.Log($"Смена состояния: {oldStateId}{newStateId}");
    }

    public Task AfterDelete(CustomHooksContext context, Project entity)
        => Task.CompletedTask;

    public Task BeforeDelete(CustomHooksContext context, Project entity)
        => Task.CompletedTask;

    public Task AfterSetState(CustomHooksContext context, Project entity, Guid oldStateId, Guid newStateId)
        => Task.CompletedTask;

    public Task BeforeStartWorkflow(CustomHooksContext context, Project entity)
        => Task.CompletedTask;
}

Порядок вызова хуков

Методы интерфейса IEntityTypeCustomHooks<TEntity> вызываются системой в определённой последовательности в рамках операции над сущностью.

Все хуки выполняются в одной транзакции. Если в любом из них возникает исключение — операция отменяется и изменения не сохраняются.

CRUD операции

При создании или обновлении сущности:

BeforeUpsert
↓
сохранение сущности
↓
AfterUpsert
↓
BeforeCommit
↓
commit транзакции
↓
AfterCommit

При удалении сущности:

BeforeDelete
↓
удаление сущности
↓
AfterDelete
↓
BeforeCommit
↓
commit транзакции
↓
AfterCommit

Переход состояния

При изменении состояния жизненного цикла:

BeforeSetState
↓
смена состояния
↓
AfterSetState
↓
BeforeCommit
↓
commit транзакции
↓
AfterCommit

Запуск workflow

BeforeStartWorkflow
↓
запуск workflow
↓
BeforeCommit
↓
commit транзакции
↓
AfterCommit

Особенности

  • Все хуки до AfterCommit выполняются внутри транзакции.
  • AfterCommit выполняется после сохранения изменений.
  • Интеграции и внешние вызовы рекомендуется выполнять в AfterCommit.

Содержание

Назначение Общая структура интерфейса Хуки операций с сущностью BeforeUpsert AfterUpsert BeforeDelete AfterDelete Хуки жизненного цикла BeforeSetState AfterSetState Хук запуска workflow BeforeStartWorkflow Параметры методов context detachedEntity contextEntity Пример реализации Порядок вызова хуков CRUD операции Переход состояния Запуск workflow Особенности
Ничего не найдено

Перейти на русскую версию?