Это продолжение статей:
» Разработка → Кроссплатформенное использование классов .Net из неуправляемого кода. Или аналог IDispatch на Linux
» Разработка → Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux
С того времени добавил поддержку методов с параметрами по умолчанию, вызов методов расширений, вывод типов для дженерик методов, поддержка объектов реализующих IDynamicMetaObjectProvider (ExpandoObject,DynamicObject), добавление синонимов к членам типа и асинхронное программирование на 1С!
В свое время написал статью .Net в 1С. На примере использования HTTPClient,AngleSharp. Удобный парсинг сайтов с помощью библиотеки AngleSharp, в том числе с авторизацией аля JQuery с использованием CSS селекторов. Динамическая компиляция
В котором был пример использования методов расширения, дженерик методов, параметров по умолчанию. И в итоге код с использованием IReflect был очень далек от реального на C#. В новой версии я попытался максимально приблизить код на 1С к оригиналу.
Разберем пример на C#
Вот его аналог на 1С:
Обращу внимание на несколько моментов. Конструкция:
На 1С выглядит так:
Я использовал зарезервированное слово in Для создания потомка DynamicObject, в котором сохраняются объект и дженерик аргументы, а затем через TryInvokeMember получаем имя метода и параметры и находим нужный метод и выполняем.
Пока для дженериков не реализовал методы с дефолтными параметрами и параметрами массивами.
Для дженериков выводится типы для таких конструкций:
Пример на 1С
Тип выводится из List приводя к Ilist и сравнивая результат с типом 3 параметра.
Меня очень часто упрекали за Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент.
1. Нет кроссплатформенности
2. Нет рускоязычных синонимов.
Ну с кроссплатформенностью подсобил MS, и сделал кроссплатформенную компоненту. И сделал возможность добавлять синонимы к типу.
Синонимы можно использовать и из расширений. Например:
Теперь можно вызвать:
Так же можно вызывать расширения и для дженерик методов. В том числе с выводом по ограничению.
Метод расширения ApiExtensions:
Выводится тип this TElement по ограничению IElement
Пока не нашел способа просмотреть все загруженные сборки. Поэтому поиск расширений пока ведется в сборке где находится тип с вызываемым методом. Надеюсь осенью выйдет релиз с большими возможностями.
Кроме того добавил более краткую запись получения интерфейса
Вместо
Можно использовать as
Примеры и исходники можно скачать Здесь
В следующей статье Асинхронное программирование в 1С через .Net Native ВК расскажу про асинхронное программирование в 1С.
» Разработка → Кроссплатформенное использование классов .Net из неуправляемого кода. Или аналог IDispatch на Linux
» Разработка → Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux
С того времени добавил поддержку методов с параметрами по умолчанию, вызов методов расширений, вывод типов для дженерик методов, поддержка объектов реализующих IDynamicMetaObjectProvider (ExpandoObject,DynamicObject), добавление синонимов к членам типа и асинхронное программирование на 1С!
В свое время написал статью .Net в 1С. На примере использования HTTPClient,AngleSharp. Удобный парсинг сайтов с помощью библиотеки AngleSharp, в том числе с авторизацией аля JQuery с использованием CSS селекторов. Динамическая компиляция
В котором был пример использования методов расширения, дженерик методов, параметров по умолчанию. И в итоге код с использованием IReflect был очень далек от реального на C#. В новой версии я попытался максимально приблизить код на 1С к оригиналу.
Разберем пример на C#
var config = Configuration.Default.WithDefaultLoader().WithCookies(); // Устанавливаем адрес страницы сайта var address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes"; // загружаем страницу и разбираем её var document = BrowsingContext.New(config).OpenAsync(address).Result; // найдем <a href="/wiki/The_Big_Bang_Theory" title="The Big Bang Theory">The Big Bang Theory</a> var rowSelector = "a[title='The Big Bang Theory']"; var HtmlAnchorElement = document.QuerySelector<IHtmlAnchorElement>(rowSelector); rowSelector="form#searchform"; var FormElement = doc.<IHtmlFormElement>QuerySelector(rowSelector));
Вот его аналог на 1С:
СборкаAngleSharp=ъ(Врап.Сборка("AngleSharp")); Assembly=ъ(СборкаAngleSharp.GetType()); Врап.ДобавитьСиноним(Assembly.ПолучитьСсылку(),"Тип","GetType"); // Теперь мы можем использовать синоним Тип AngleSharp_Configuration=ъ(СборкаAngleSharp.Тип("AngleSharp.Configuration")); // Или вызвать реальный метод GetType HtmlParser=ъ(СборкаAngleSharp.GetType("AngleSharp.Parser.Html.HtmlParser")); //Получим типы BrowsingContext = ъ(СборкаAngleSharp.Тип("AngleSharp.BrowsingContext")); Configuration=ъ(СборкаAngleSharp.Тип("AngleSharp.Configuration")); // Методы рсширения ConfigurationExtensions // public static IConfiguration WithDefaultLoader(this IConfiguration configuration, Action<LoaderService> setup = null, IEnumerable<IRequester> requesters = null); // public static IConfiguration WithCookies(this IConfiguration configuration); config = ъ(ъ(ъ(Configuration.Default).WithDefaultLoader()).WithCookies()); address = "https://en.wikipedia.org/wiki/List_of_The_Big_Bang_Theory_episodes"; context = ъ(BrowsingContext.New(config.ПолучитьСсылку())); // Загрузим начальную страницу // Метод расширения BrowsingContextExtensions //public static Task<IDocument> OpenAsync(this IBrowsingContext context, string address); document = ъ(ъ(context.OpenAsync(address)).Result); rowSelector = "a[title='The Big Bang Theory']"; // Метод расширения ApiExtensions //public static TElement QuerySelector<TElement>(this IParentNode parent, string selectors) where TElement : class, IElement; HtmlAnchorElement=ъ(ъ(document.in(IHtmlAnchorElement.ПолучитьСсылку())).QuerySelector(rowSelector)); //Метод расширения ApiExtensions //public static Task<IDocument> ApiExtensions.NavigateAsync<TElement>(this TElement element) where TElement : IUrlUtilities, IElement; //Вывод типа this TElement по ограничению IElement doc=ъ(ъ(HtmlAnchorElement.NavigateAsync()).Result); rowSelector="form#searchform"; FormElement = ъ(ъ(doc.in(IHtmlFormElement.ПолучитьСсылку())).QuerySelector(rowSelector)); Сообщить("OuterHtml="+FormElement.OuterHtml);
Обращу внимание на несколько моментов. Конструкция:
document.QuerySelector<IHtmlAnchorElement>(rowSelector);
На 1С выглядит так:
HtmlAnchorElement=ъ(ъ(document.in(IHtmlAnchorElement.ПолучитьСсылку())).QuerySelector(rowSelector));
Я использовал зарезервированное слово in Для создания потомка DynamicObject, в котором сохраняются объект и дженерик аргументы, а затем через TryInvokeMember получаем имя метода и параметры и находим нужный метод и выполняем.
Пока для дженериков не реализовал методы с дефолтными параметрами и параметрами массивами.
Для дженериков выводится типы для таких конструкций:
public K ДженерикМетод3<K>(IList<K> param1, int param2, K param3)
Пример на 1С
List=ъНовый("System.Collections.Generic.List`1[System.String]"); Сообщить(Тест.ДженерикМетод3(List.ПолучитьСсылку(),3,"Привет3"));
Тип выводится из List приводя к Ilist и сравнивая результат с типом 3 параметра.
Меня очень часто упрекали за Использование сборок .NET в 1С 7.x b 8.x. Создание внешних Компонент.
1. Нет кроссплатформенности
2. Нет рускоязычных синонимов.
Ну с кроссплатформенностью подсобил MS, и сделал кроссплатформенную компоненту. И сделал возможность добавлять синонимы к типу.
СборкаAngleSharp=ъ(Врап.Сборка("AngleSharp")); Assembly=ъ(СборкаAngleSharp.GetType()); Врап.ДобавитьСиноним(Assembly.ПолучитьСсылку(),"Тип","GetType"); // Теперь мы можем использовать синоним Тип AngleSharp_Configuration=ъ(СборкаAngleSharp.Тип("AngleSharp.Configuration")); // Или вызвать реальный метод GetType HtmlParser=ъ(СборкаAngleSharp.GetType("AngleSharp.Parser.Html.HtmlParser"));
Синонимы можно использовать и из расширений. Например:
public static class РасширенияДляТестовый { public static string ПолучитьСтрокуИзРасширенияСпарам(this Тестовый тест,string Str) { return тест.ПолучитьСтроку()+" "+ Str; } }
Теперь можно вызвать:
// Ищем сборку по путям переданным при создании компоненты //ПодключитьВнешнююКомпоненту(ИмяФайла, "NetObjectToNative",ТипВнешнейКомпоненты.Native); // Врап = Новый("AddIn.NetObjectToNative.LoaderCLR"); // Врап.СоздатьОбертку(CoreClrDir,ДиректорияNetObjectToNative,""); // Где // CoreClrDir Это директория где лежат основные библиотеки .Net и в частности coreclr // ДиректорияNetObjectToNative директория где лежит эта сборка // на данный момент все пользовательские сборки нужно сохранять рядом с ней //Пример использования //СборкаHttpClient=ъ(Врап.Сборка("System.Net.Http",истина)); //HttpClient=ъ(СборкаHttpClient.GetType("System.Net.Http.HttpClient")); // Можно опускать разрешение. По умолчанию Dll РасширенияДляТестовый=ъ(СборкаТестовый.Тип("TestDllForCoreClr.РасширенияДляТестовый")); Врап.ДобавитьСиноним(РасширенияДляТестовый.ПолучитьСсылку(),"GetStringFromExtensionWithParams","ПолучитьСтрокуИзРасширенияСпарам"); // Вызовем по оригигальному названию Сообщить(Тест.ПолучитьСтрокуИзРасширенияСпарам("Привет")); // Вызовем по синониму Сообщить(Тест.GetStringFromExtensionWithParams("Привет из GetStringFromExtensionWithParams"));
Так же можно вызывать расширения и для дженерик методов. В том числе с выводом по ограничению.
Метод расширения ApiExtensions:
public static Task<IDocument> ApiExtensions.NavigateAsync<TElement>(this TElement element) where TElement : IUrlUtilities, IElement;
Выводится тип this TElement по ограничению IElement
doc=ъ(ъ(HtmlAnchorElement.NavigateAsync()).Result);
Пока не нашел способа просмотреть все загруженные сборки. Поэтому поиск расширений пока ведется в сборке где находится тип с вызываемым методом. Надеюсь осенью выйдет релиз с большими возможностями.
Кроме того добавил более краткую запись получения интерфейса
Вместо
Перечислимый=ъ(Врап.ПолучитьИнтерфейс(Объект.ПолучитьСсылку(),"IEnumerable"));
Можно использовать as
Перечислимый=ъ(Объект.as("IEnumerable")); Перечислитель=ъ(Перечислимый.GetEnumerator()); // На всякий случай приведем к Интерфейсу IEnumerator Перечислитель=ъ(Перечислитель.as("IEnumerator"));
Примеры и исходники можно скачать Здесь
В следующей статье Асинхронное программирование в 1С через .Net Native ВК расскажу про асинхронное программирование в 1С.
