В классе Бизнес-операции должен быть реализован интерфейс IBusinessOperation. Для удобства разработчика модуль XafariBusinessOperationsModule поставляет готовый базовый класс BusinessOperationBase. При разработке прикладной Бизнес-операции рекомендуется реализовать наследника BusinessOperationBase.
BusinessOperationBase выполняет всю базовую функциональность бизнес-операций: генерирует и обрабатывает события, реализует свойства и методы, продекларированные интерфейсом IBusinessOperation. Кроме того, данный класс предоставляет множество статических методов для доступа к метаинформации о самой Бизнес-операции, фабричные методы создания экземпляров Бизнес-операций. Полная информация о классе BusinessOperationBase представлена в документации.
Если класс Бизнес-операции разрабатывается с использованием BusinessOperationBase, то в большинстве случаев достаточно описать параметры Бизнес-операции (входные, выходные) и контекст (при необходимости).
Рассмотрим пример контекстной списковой Бизнес-операции, использующей BusinessOperationBase в качестве базового класса. Бизнес-операция решает следующую задачу: изменить стоимость фрахта в документе Order на заданную величину (в процентах).
/// <summary>
/// Контекстная бизнес-операция. Выполняется в контексте бизнес-объектов "Заказы".
/// Позволяет изменить стоимость фрахта требуемых заказов.
/// </summary>
[DisplayName("Изменение стоимости фрахта")]
[Description("Изменение стоимости фрахта на заданную величину в %.")]
[ImageName("BO_Sale")]
[ExecutionWay(ExecutionWays.Synchronous)]
[ContextViewType(ContextViewType.Any)]
[BusinessOperationCategory("Заказы"), BusinessOperationCategory]
[DefaultOperationService(typeof(ChangeFreightContextDefaultImpl))]
public class ChangeFreightContext : BusinessOperationBase
{
private List<string> _processedOrdersLog;
/// <summary>
/// Контекстное свойство отмечено специальным атрибутом. Анализируя тип этого свойства фреймворк "поймет",
/// для какого контекста предназначена бизнес-операция и инициализирует это свойство
/// перед ее выполнением.
/// </summary>
[ContextProperty(ObjectsCriteria = "[Number] != '010248'",
ObjectsCriteriaMode = TargetObjectsCriteriaMode.TrueForAll)]
public ICollection<Order> Orders { get; set; }
/// <summary>
/// Входной параметр бизнес-операции. Фреймворк определяет входные параметры по наличию паблик-сеттера.
/// В момент запуска бизнес-операции на основе входных параметров генерируется представление для
/// их ввода пользователем.
/// </summary>
[DisplayName("Величина, %")]
public double Percent { get; set; }
/// <summary>
/// Выходной параметр. Содержит текстовые сообщения об обработанных заказах.
/// </summary>
public List<string> ProcessedOrdersLog
{
get { return _processedOrdersLog ?? (_processedOrdersLog = new List<string>()); }
}
}
В приведенном примере применено множество атрибутов с указанием значений по умолчанию. Так сделано в целях демонстрации возможностей использования атрибутов. В конкретном прикладном проекте их можно вообще не указывать. Информация по конкретным атрибутам представлена в следующих статьях:
- Атрибуты, применяемые к классам бизнес-операций
- Атрибуты, применяемые к полям классов бизнес-операций
Все public-свойства Бизнес-операции рассматриваются как ее параметры. Часть параметров будет проинициализирована фреймворком перед выполнением Бизнес-операции. Рассмотрим подробнее свойства из примера.
Свойство public ICollection<Order> Orders.
Благодаря наличию атрибута ContextPropertyAttribute данное свойство рассматривается фреймворком как контекст, в котором будет доступна Бизнес-операция.
Если тип контекстного свойства не является коллекцией, то Бизнес-операция считается одиночной. Такая Бизнес-операция может применяться только к одному объекту. Если в List View выделить несколько объектов, то одиночные Бизнес-операции станут недоступны для запуска из пользовательского интерфейса. При выполнении Бизнес-операции фреймворк инициализирует контекстное свойство ссылкой на текущий объект.
В качестве типа контекстного свойства может быть указан обобщенный тип коллекции. Такая ситуация продемонстрирована в вышеприведенном примере. Параметром обобщенного типа выступает бизнес-объект Order. Такая Бизнес-операция рассматривается как списковая. Обобщенный тип коллекции может быть как абстрактным, например, ICollection<T>, так и конкретным, например, List<T>. Список поддерживаемых типов приведен в описании класса CollectionCreatorFactory. Фреймворк создает экземпляр подходящего класса коллекции, наполняет его ссылками на выбранные объекты, либо ссылкой на текущий объект (если объекты не выбраны) и инициализирует им контекстное свойство Бизнес-операции.
Замечание:
Платформа Xafari предоставляет технологию eXtensions Framework (XF) для разработки бизнес-модели приложения. Контекстные Бизнес-операции корректно работают с бизнес-объектами, построенными по данной технологии.
Поведение фреймворка при применении атрибута ContextPropertyAttribute сразу к нескольким свойствам бизнес-операции не определено и такая ситуация считается некорректной. К ошибкам компиляции или выполнения это не приведет, но фреймворк в качестве контекста может выбрать любое из них.
Бизнес-операция представлена узлом Application|Xafari|BusinessOperations|<BusinessOperation item> в Модели Приложения. Сведения о контексте содержаться в свойствах ContextDataType, ContextProperty, ContextTypeMatchMode, ContextObjectsCriteria, ContextObjectsCriteriaMode (см. IModelBusinessOperationContext).
Свойство public double Percent.
Если в классе Бизнес-операции описано свойство с public-сеттером, то фреймворк будет рассматривать его как входной параметр Бизнес-операции. Перед запуском Бизнес-операции фреймворк генерирует Detail View для ввода параметров. Detail View содержит Property Editors для всех входных параметров, исключение составляют лишь контекстное свойство и свойство IBusinessOperationManaged.Process. Свойства без public-сеттера не будут представлены на Detail View. Для генерации Detail View используется объект класса BODynamicPropertiesObject (являющийся наследником класса DynamicPropertiesObject).
Идентификатор Detail View генерируется по шаблону BODPO_InputParameters_BusinessOperationId_DetailView, где BusinessOperationId – идентификатор Бизнес-операции, для которой сгенерировано View. Для получения идентификатора View в прикладном коде (например, для кастомизации View в своем контроллере) можно использовать статический метод BOMethodRunner.GetInputParametersDetailViewId.
Все параметры Бизнес-операции перечислены в узле Application|Xafari|BusinessOperations|<BusinessOperation item>|Parameters Модели Приложения (см. IModelBusinessOperation, IModelBusinessOperationParameter).
Применяемые к параметрам Бизнес-операций атрибуты описаны в статье Атрибуты, применяемые к полям классов бизнес-операций.