Пример работы механизма
замещения
Для практического ознакомления с механизмом замещения реализуем следующий пример: создадим замещаемый (базовый) класс, виртуальный метод которого возвращает сумму двух чисел. В замещающем (производном) классе поменяем логику: возвращаемую сумму умножим на число, переданное в конструктор класса. Для вызова реализованной логики добавим веб-сервис.
Создание замещаемого класса
- Откройте раздел «Конфигурация».
- Создайте пользовательский пакет BpmSubstitutionMechanism. В области работы с пакетами раздела «Конфигурация» выберите созданный пакет. В свойствах пакета в области «Зависит от пакетов» добавьте пакет ProductCore.
- Из списка «Добавить» панели инструментов рабочей области раздела «Конфигурация» выберите «Исходный код».
Рисунок 1 — Создание замещаемого класса

- Заполните свойства «Заголовок» и «Код»:
Рисунок 2 — Свойства замещаемого класса

- Создайте класс BpmBaseCalculator. Добавьте один виртуальный метод, возвращающий сумму двух чисел, переданных в качестве параметра метода.
// Система позволяет использовать любое пространство имен в коде схемы «Исходный код».
// Выбор пространства имен зависит от команды разработки или регламентов компании.
// В данном пример воспользуемся пространством BPMSoft.Configuration.
namespace BPMSoft.Configuration
{
/// <summary>
/// Замещаемый (базовый) класс.
/// </summary>
public class BpmBaseCalculator
{
/// <summary>
/// Базовый виртуальный метод, который будет переопределен в замещающем классе. Метод возвращает сумму двух чисел.
/// </summary>
public virtual int GetAmount(int firstNumber, int secondNumber)
{
return firstNumber + secondNumber;
}
}
}
- Сохраните и опубликуйте схему.
Создание замещающего класса
- Откройте раздел «Конфигурация».
- Выберите пакет, в который хотите добавить замещающий класс. Обратите внимание на то, что замещаемый класс должен находится либо в том же пакете, что и замещающий, либо пакет с замещаемым классом должен быть добавлен как зависимый в пакет с замещающим классом. Сделать это можно через свойства пакета. В данном примере используется тот же пакет BpmSubstitutionMechanism.
- Из списка «Добавить» панели инструментов рабочей области раздела «Конфигурация» выберите «Исходный код».
- Заполните свойства «Заголовок» и «Код»:
Рисунок 3 — Свойства замещающего класса
- Создайте новый класс BpmCalculator, который наследуется базового класса BpmBaseCalculator. Добавьте атрибут Override перед определением класса. Добавьте поле целочисленное поле Rate. Переопределите метод GetAmount, как показано в примере кода.
namespace BPMSoft.Configuration
{
// В данном пространстве имен находится атрибут Override.
using BPMSoft.Core.Factories;
/// <summary>
/// Замещающий (производный) класс.
/// </summary>
// Атрибут Override указывается для построения дерева зависимостей замещающих и замещаемых типов.
// Атрибут указывает на то, что данный класс являются замещающим.
[Override]
public class BpmCalculator : BpmBaseCalculator
{
/// <summary>
/// Коэффициент.
/// </summary>
public virtual int Rate { get; private set; }
/// <summary>
/// Конструктор замещающего класса.
/// </summary>
public BpmCalculator(int rateValue)
{
Rate = rateValue;
}
/// <summary>
/// Замещенный метод. Возвращает сумму двух чисел умноженную на коэффициент.
/// </summary>
public override int GetAmount(int firstNumber, int secondNumber)
{
return (firstNumber + secondNumber) * Rate;
}
}
}
- Сохраните и опубликуйте схему.
Демонстрация работы
Для вызова метода замещающего и замещаемого классов создадим пользовательский веб-сервис.
- Откройте раздел «Конфигурация».
- Выберите пакет, в который хотите добавить сервис. Обратите внимание на то, что сервис должен находиться в том же пакете, что и замещаемый, и замещающий класс. Если это не так, добавьте в пакет с сервисом необходимые зависимости. В данном примере используется тот же пакет BpmSubstitutionMechanism.
- Из списка «Добавить» панели инструментов рабочей области раздела «Конфигурация» выберите «Исходный код».
- Заполните свойства «Заголовок» и «Код»:
Рисунок 4 — Свойства веб-сервиса

- Реализуйте Get-метод веб-сервиса, в котором вызывается метод подсчета замещаемого и замещающего классов.
namespace BPMSoft.Configuration
{
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using BPMSoft.Web.Common;
using BPMSoft.Core.Factories;
using System;
/// <summary>
/// Пользовательский сервис.
/// </summary>
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class BpmAmountService : BaseService
{
/// <summary>
/// Возвращает строку с результатом вызова методов GetAmount замещающего и замещаемого классов.
/// </summary>
[OperationContract]
[WebGet(RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
public string GetAmount(int firstNumber, int secondNumber)
{
try
{
/* Создание экземпляра замещаемого класса. */
var bpmBaseCalculator = new BpmBaseCalculator();
/* Создание экземпляра замещающего класса через фабрику замещаемых объектов. */
var bpmCalculator = ClassFactory.Get<BpmBaseCalculator>(new ConstructorArgument("rateValue", 2));
/* Получение результата работы метода GetAmount(). Будет вызван метод исходного класса BpmBaseCalculator без замещения. */
int baseCalculatorResult = bpmBaseCalculator.GetAmount(firstNumber, secondNumber);
/* Получение результата работы метода GetAmount(). Будет вызван метод класса BpmCalculator, который замещает BpmBaseCalculator. */
int bpmCalculatorResult = bpmCalculator.GetAmount(firstNumber, secondNumber);
/* Отображение на странице результата выполнения. */
return string.Format("Результат замещаемого класса: {0}; Результат замещающего класса : {1}", baseCalculatorResult.ToString(), bpmCalculatorResult.ToString());
}
catch (Exception ex)
{
throw new Exception($"В пользовательском сервисе возникла ошибка:{ex} {ex.Message}");
}
}
}
}
- Сохраните и опубликуйте схему.
Вызовите метод веб-сервиса из браузера. Для этого в адресную строку введите адрес:
[Адрес приложения]/0/rest/BpmAmountService/GetAmount?firstNumber=25&secondNumber=125, где
- [Адрес приложения] — адрес сервиса;
- BpmAmountService — название веб-сервиса;
- GetAmount — название вызываемого метода;
- firstNumber и secondNumber — параметры веб-сервиса.
В .NET 8 версии приложения для вызова веб-сервиса не нужно использовать приставку /0.
Рисунок 5 — Результат вызова
