Расширенные методы загрузки внешних библиотек в http-сервисах OneScript

В статье описаны расширенные методы загрузки внешних библиотек в http-сервисах OneScript на примере механизма фоновых заданий.

Введение

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

В настоящее время и OneScript и 1С:Предприятия имеют развитые средства для обеспечения повторного использования кода, однако они недостаточно совместимы между собой, что приводит к необходимости редактирования кода при переносе между этими платформами. Первым шагом, для улучшения переносимости кода между платформами, стала реализация концепции общих модулей в http-сервисах OneScript, однако опыт, полученный мною при написании демонстрационных конфигураций показал, что периодически возникают ситуации, когда различия в реализации концепции библиотек дают о себе знать, что приводит к непроизводительной трате ресурсов на адаптацию кода под разные платформы. В качестве примера, можно привести фрагмент кода, иллюстрирующий использование библиотеки фоновых заданий из этой статьи.

Вроде бы все неплохо, однако для доступа к менеджеру фоновых заданий, сначала необходимо создать экземпляр объекта соответствующего типа, в то время, как в 1С:Предприятие уже существует глобальное свойство с именем ФоновыеЗадания. Эти различия приводят к примерно следующим конструкциям:

 
// Создаем объект менеджера фоновых заданий. Только для OneScript

//<OneScript>

ФоновыеЗадания = Новый МенеджерФоновыхЗаданийWeb;

//<!OneScript>

 

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

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

О том, что из этого получилось – читайте ниже.  

Как это работает

Процесс загрузки внешних библиотек происходит при начальной инициализации “движка” OneScript, который в дальнейшем будет выполнять Ваш код, поэтому рассмотрим его подробнее.

Инициализация происходит в несколько этапов:

Создание и инициализация “движка”

На этом этапе создается экземпляр среды выполнения, которая содержит стандартные функции OneScript и не содержит каких-либо внешних библиотек или компонентов.

Загрузка сборок внешних библиотек

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

Создание глобальных свойств для общих модулей

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

Создание глобальных свойств для внешних библиотек

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

Компиляция и установка значений глобальных свойств общих модулей

На данном этапе происходит компиляция исходного кода общих модулей и скомпилированные объекты присваиваются соответствующим глобальным свойствам.

Создание и установка глобальных свойств внешних библиотек

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

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

Реализация

Как можно увидеть, для успешной загрузки необходимо обеспечить две функции — возврат списка имен свойств, а также функцию собственно создания экземпляров объектов, и установка значений соответствующих свойств.

Поскольку у нас могут быть уже готовые компоненты, написанные ранее, нам необходимо создать класс-загрузчик, который должен реализовывать нижеследующий интерфейс:

   

 
public interface ILibraryAsPropertiesLoader

{
// Метод возвращает список имен глобальных свойств, которые будут созданы
List<string> GetPropertiesNamesForInjecting(string info);
// Метод создает экземпляры свойств и присваевает свойствам соответствующие значения
void AssignPropertiesValues(HostedScriptEngine engine);

}

 

 

В случае фоновых заданий, код класса-загрузчика выглядит следующим образом:

  

 
public class BackgroundJobs : ILibraryAsPropertiesLoader
{
public List<string> GetPropertiesNamesForInjecting(string info)
{
List<string> propNames = new List<string>();
propNames.Add("ФоновыеЗадания");

return propNames;
}

public void AssignPropertiesValues(HostedScriptEngine engine)
{
engine.EngineInstance.Environment.SetGlobalProperty("ФоновыеЗадания", new WebBackgroundJobsManagerImpl());
}
}

Собственно все, что он делает – это создает экземпляр класса МенеджерФоновыхЗаданийWeb (WebBackgroundJobsManager) и устанавливает значение свойства ФоновыеЗадания равным ссылке на экземпляр класса.

В данном конкретном случае, класс-загрузчик был добавлен непосредственно в сборку, реализующую механизм фоновых заданий, однако, при отсутствии такой возможности (откомпилированный бинарный файл), Вы можете создать отдельную сборку для загрузки и использовать данный метод без изменения кода компоненты. Также следует отметить, что в сборках может быть несколько классов-загрузчиков.

Настройка и использование

Для использования внешних библиотек, а также возможности их загрузки, соответствующие сборки необходимо поместить в папку Bin, Вашего приложения. В дальнейшем предположим, что мы имеем две сборки (dll). Одну – содержащую внешнюю компоненту и вторую, которая реализует класс-загрузчик.

Сначала, необходимо включить сборку, которая содержит внешнюю компоненту в список сборок, которые будут загружены в среду выполнения. Это можно сделать, добавив нижеследующую строку в раздел appSettings, файла web.config Вашего web-приложения:

<add key="ИмяСборки" value="attachAssembly" />

Далее, нам необходимо дать приложению информацию о классах-загрузчиках. Это можно сделать, добавив строки следующего вида:

<add key="propertiesInjector;WebBackgroundJobs;OneScript.HTTPService.BackgroundJobs" value="" />

Где:

propertiesInjector – признак того, что информация относится к загрузчику свойств.

WebBackgroundsJob – имя сборки-загрузчика (в нашем конкретном случае загрузчик находится в сборке внешней компоненты).

OneScript.HTTPService.BackgroundJobs – имя типа класса-загрузчика.

value – произвольная строка, которая передается в функцию получения списка свойств.

После подключения сборки WebBackgroundJobs вышеуказанным способом, код использования этого механизма в OneScript становится практически идентичным коду платформы 1С:Предприятие:

 

 
// Запускаем фоновые задания на выполнение

МассивПараметров = Новый Массив;
МассивПараметров.Добавить(1);
МассивПараметров.Добавить("1.txt");

ФоновыеЗадания.Execute("Тестовый.ТестовоеФЗ", МассивПараметров, "Ключ1", "Описание1");

МассивПараметров = Новый Массив;
МассивПараметров.Добавить(1);
МассивПараметров.Добавить("2.txt");

ФоновыеЗадания.Execute("Тестовый.ТестовоеФЗ", МассивПараметров);

// Получаем все выполняющиеся задания
МассивЗаданий = ФоновыеЗадания.ПолучитьФоновыеЗадания();

// Ожидаем завершения выполнения запущеных заданий
ФоновыеЗадания.ОжидатьЗавершения(МассивЗаданий);

// Продолжаем выполнение

 

 То есть по сути он стал полностью переносимым на уровне синтаксиса. Поскольку определение класса внешней компоненты также известно системе, код в старом стиле будет также работоспособным.

Заключение

С использованием данного подхода можно реализовать модульное добавление необходимых объектов платформы 1С:Предприятие в OneScript, при этом обеспечив переносимость кода. В следующей статье планируется описать механизм обработок, созданный по данной схеме. Также, при необходимости, реализацию этих компонентов можно поменять (скажем, не нравится Вам текущая реализация механизма фоновых заданий), без необходимости пересборки остальных частей web-приложения.

P.S.

Хочу выразить благодарность Андрею Овсянкину за помощь при адаптации библиотек к платформе 1.0.20.

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *