Обертки для сторонних библиотек, которые поставляются в составе платформы Sungero

18 1

В статье разберу рекомендации, как уменьшить размер пакета разработки, если в прикладном коде используются сторонние библиотеки, которые поставляются в составе платформы Sungero, то есть уже имеются в bin-каталогах сервисов Directum RX.

Начнем с поставленной задачи.

Необходимо загрузить Общероссийский классификатор занятий (ОКЗ) в одноименный справочник в Directum RX. ОКЗ хранится в Excel-файле. Механизм загрузки должен запускаться клиентскими средствами без использования утилит.

Есть два варианта решения:

  1. Добавить в сторонние библиотеки модуля библиотеку DocumentFormat.OpenXml.dll и работать напрямую с этой библиотекой в прикладном коде RX.
  2. Создать обертку библиотеки DocumentFormat.OpenXml.dll, в которой будет выполнена нужная функциональность. Далее обертку добавить в сторонние библиотеки модуля и из прикладного кода RX вызвать нужный метод из обертки.

Я не претендую на инновацию, потому как подобные обертки есть в коробочном решении, например, Sungero.AsposeExtensions.dll в сторонних библиотеках модуля Sungero.Docflow. Просто мне кажется, использование таких оберток имеют ряд плюсов, поэтому родилась идея написать статью-инструкцию как это использовать в своих проектах.

Минусы использования первого варианта:

  1. Большой размер выгружаемого пакета с разработкой (5,74 МБ).
  2. Долгая публикация разработки на тест/прод сервера, которая может закончится ошибкой по тайм ауту.

Плюсы использования второго варианта:

  1. Уменьшается размер выгружаемого пакета с разработкой (7,5 КБ)
  2. Уменьшается время публикации на тест/прод.
  3. Уменьшается время на отладку. Отладка в Visual Studio значительно быстрее, чем в Development Studio

Создание обертки в Visual Studio 2019

  1. Создаем проект в Visual Studio, выбираем шаблон проекта.

  1. Целевую платформу выбираем .NET Standard 2.0.
    В версии 4.1 веб-сервер, среда разработки и все микросервисы Directum RX переведены на версию .NET Core 3.1. При этом сторонние библиотеки для прикладной разработки Directum RX должны быть собраны под .NET Standard 2.0. Поэтому нам необходимо создать проект именно с такой целевой платформой .NET Standard 2.0.

  1. Добавим в ссылки на библиотеки DocumentFormat.OpenXml.dll и System.IO.Packaging.dll из bin каталога сервиса SungeroWebServer (\DirectumLauncher\etc\_builds_bin\SungeroWebServer). Например, в Visual Studio 2019 последовательность следующая: в обозревателе проекта развернуть проект, далее Зависимости-ПКМ-Добавить ссылку на проект-Обзор-Выбираем библиотеки DocumentFormat.OpenXml.dll и System.IO.Packaging.dll.

  1. Создадим новый класс RowRCO для хранения информации одной записи классификатора:
public class RowRCO
{
	public int NumberRow;
	public string Code;
	public string ControlNumber;
	public string NameGroup;
}
  1. Создадим новый класс GetDataFromExcel, в котором реализуем метод GetExcelRows получения списка записей классификатора из excel файла. Входные параметры поток, в котором содержится excel документ и номер стартовой строчки в excel файле. На выходе метод возвращает список записей классификатора.
public class GetDataFromExcel
{
	public static List<RowRCO> GetExcelRows(Stream inputStream, int nrowstart)
	{
		var result = new List<RowRCO>();

		using (var document = SpreadsheetDocument.Open(inputStream, false))
		{
			var workbookPart = document.WorkbookPart;
			var stringTablePart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
			var stringTable = stringTablePart.SharedStringTable;
			var worksheetPart = workbookPart.WorksheetParts.First();
			var sheet = worksheetPart.Worksheet;
			var cells = sheet.Descendants<Cell>();
			var rows = sheet.Descendants<Row>();
			var maxElements = rows.First().Elements<Cell>().Count();

			//определим количество строк
			int counRows = GetCountRows(rows, nrowstart, stringTable);

			int irow = 1;
			foreach (var row in rows)
			{
				if (irow < nrowstart) { irow++; continue; }

				var columnsValue = GetColumnsValue(row, stringTable);

				var element = new RowRCO()
				{
					NumberRow = irow,
					Code = GetValueCell(columnsValue, 0),
					ControlNumber = GetValueCell(columnsValue, 1),
					NameGroup = GetValueCell(columnsValue, 2)
				};

				result.Add(element);

				irow++;

				if (irow >= counRows + nrowstart)
					break;
			}
		}

		return result;
	}
}
  1. Собираем решение и получаем обертку Armadoc.OpenXMLExtensions.dll.
  2. На этом работа в Visual Studio закончена.

Разработка на стороне Directum Development Studio

  1. Добавляем обертку Armadoc.OpenXMLExtensions.dll в сторонние библиотеки в нужный модуль.
  2. Далее в программном коде обращаемся к методу GetExcelRows
Logger.Debug("LoadingRCO: Начало импорта ОКЗ");
List<Armadoc.OpenXMLExtensions.RowRCO> dataFromExcel;
try
{
  using (var inputStream = new System.IO.MemoryStream())
  {
    document.LastVersion.Body.Read().CopyTo(inputStream);
    dataFromExcel = Armadoc.OpenXMLExtensions.GetDataFromExcel.GetExcelRows(inputStream, document.NumberStartImport.Value);
  }
}
catch (Exception ex)
{
  Logger.ErrorFormat("LoadingRCO: Ошибка при получении данных: {0}", ex.ToString());
  throw AppliedCodeException.Create(string.Format("Ошибка при получении данных: {0}", ex.Message));
}

Заключение

В конкретном примере обертка получилась размером 7,5 КБ, что значительно меньше размера 5,74 МБ библиотеки DocumentFormat.OpenXml.dll. Также отмечу, что размер пакета будет зависеть от области действия сторонней сборки. Например, если выбрать «Только сервер», то размер пакета примерно увеличиться на 5,74 МБ, а если выбрать «Клиент и сервер», то размер пакета будет увеличен уже на 11,48 МБ. В нашем же случае при использовании обертки пакет будет увеличен на 7,5 КБ и 15 КБ для «Только сервер» и «Клиент и сервер» соответственно.

18
Авторизуйтесь, чтобы оценить материал.
6
Алексей Присяжный

Ну тут скорей вопрос к разработчикам DDS - почему не пробрасываются и так доступные библиотеки платформы в область видимости. Благо в новых версиях (4.6+) стали хотя бы в изолированные области х пробрасывать.

Авторизуйтесь, чтобы написать комментарий