Это продолжение статей:
» Разработка → Кроссплатформенное использование классов .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С.