Как стать автором
Обновить

Комментарии 18

Жесть
doc=ъ(ъ(HtmlAnchorElement.NavigateAsync()).Result);
Перечислимый=ъ(Врап.ПолучитьИнтерфейс(Объект.ПолучитьСсылку(),"IEnumerable"));
Я в предыдущей статье писал, что в Native Api можно использовать только простые типы и строкию
В новой версии можно использовать as

Перечислимый=ъ(Объект.as("IEnumerable"));
    Перечислитель=ъ(Перечислимый.GetEnumerator());
    // На всякий случай приведем к Интерфейсу IEnumerator
    Перечислитель=ъ(Перечислитель.as("IEnumerator"));
      
Я думаю, речь о другом, а именно о «Ъ».

Предыдущую статью не читал, но как разработчик с 16 летним стажем, из них 10 лет на 1С — я в недоумении от этой конструкции. Названия любых методов, функций, переменных должны быть говорящими.
При этом код будет состоять из сплошных СоздатиьОбъектИзСсылки?
Даже в этом случае код будет выглядеть лучше. Любой разработчик, который будет работать после вас — скажет большое спасибо. Или, вернее, ничего не скажет — это просто будет хороший код, который не цепляет несуразностями.

Код не только должен работать и работать хорошо. Код должен быть читаемым и понятным. Помните программу в С++ 3.11, код которой напоминал набор символов, но при этом выдавал осмысленный результат в виде текста? Я даже сейчас не имею желания разобраться в ней.

PS:
Можно ведь использовать и сокращенный синоним — cog (CreateObjectFromGuid).
Я не вижу огромной разницы между $ ъ cog. Они не несут никакой смысловой нагрузки. А вот код на 1С максимально приближен к коду на C#

var config = Configuration.Default.WithDefaultLoader().WithCookies();


config = ъ(ъ(ъ(Configuration.Default).WithDefaultLoader()).WithCookies());


И ъ будет встречаться на каждом шагу. Поэтому вэб программисты испльзуя JQuery используют $ а не метод JQuery
Никто не запрещает тебе использовать вместо ъ cog. Это дело вкуса.
Согласен с автором статьи. Я не программирую на 1С (но чуток изучал для интереса) и не веб-программирую (но чуток изучал для расширения кругозора). И, тем не менее, я сразу понял, что раз этот ъ везде встречается, значит, это что-то по типу $ из JQuery.
Из-за того, что в Native Api нельзя передавать ту же ВК приходится делать такие конструкции

config = ъ(ъ(ъ(Configuration.Default).WithDefaultLoader()).WithCookies());


Если же использовать осмысленное СоздатьОбъектПоСсылке то это превращается

СоздатьОбъектПоСсылке (СоздатьОбъектПоСсылке (СоздатьОбъектПоСсылке (Configuration.Default).WithDefaultLoader()).WithCookies());


На самом деле я просто позаимствовал подход из JQuery где наравне с jQuery используется $. И никого это не раздражает
$("div.test").add("p.quote").addClass("blue").slideDown("slow");


Мне кажется, этот код вообще нужно распарсить. Компилятору всё равно, а вам удобнее.
1) Было
config = ъ(ъ(ъ(Configuration.Default).WithDefaultLoader()).WithCookies());
2) Стало
Loader = СоздатьОбъектПоСсылке(Configuration.Default).WithDefaultLoader())
Cookies = СоздатьОбъектПоСсылке(Loader.WithCookies()
Config = СоздатьОбъектПоСсылке(Cookies);

PS;
Почему ъ — это СоздатьОбъектПоСсылке? Вот здесь я не вижу ссылки, я вижу тип значения: Assembly=ъ(СборкаAngleSharp.GetType());
Где почитать про момент ввода «ъ» и программный код «ъ»?
Я в предыдущих статьях писал, что в Native Api нельзя возвращать и передавать объекты. Поэтому передается специально закодированная строка, что бы по ней определить, что это ссылка на объект при передаче в параметрах и извлечь из неё индекс в массиве хранилища объекта. Можно посмотреть код по ссылке.
ъ это из других статей

//1С при передаче по ссылке свойства ВК Список.Current
// при выходе из метода присваивает  Список.Current значение переданное изначально
// Поэтому помечаем входной параметр как Знач
//Или же делать так, если методы изменить нельзя 
// То нужно присвоить значение переменной и вызвать метод передав в параметрах эту переменную
//Стр=Список.Current; 
//Зазача=ъ(Стр);
Функция Ъ(знач Ссылка)
	
	// Создаем объект по ссылке полученной из методов .Net классов
	//Физически это строка ёЁ<Ьъ>№_%)Э?&2 содержащее 12 символов для отделения их от других строк
	//и индекс в спике исполуемых объектов на стороне .Net
	
	рез = Новый("AddIn.NetObjectToNative.NetObjectToNative");
	// И установим ссылку
	рез.УстановитьСсылку(Ссылка);    
	возврат  рез
КонецФункции // СоздатьОбъектПоСсылке()
Я в статье дал ссылку на статью где используется COM через IReflect. Там можно получать и передавать объекты, но нет возможности использовать дженерики напрямую.
Net в 1С. На примере использования HTTPClient,AngleSharp. Удобный парсинг сайтов с помощью библиотеки AngleSharp, в том числе с авторизацией аля JQuery с использованием CSS селекторов. Динамическая компиляция

Приведу код который решает ту же задачу, но он менее удобный чем с ъ

В C# есть удобный сахар в виде расширений. Например, код
Configuration.Default.WithDefaultLoader().WithCookies();


//На самом деле представляет собой

var configuration = AngleSharp.Configuration.Default;

            configuration=AngleSharp.ConfigurationExtensions.WithDefaultLoader(configuration);
            configuration = AngleSharp.ConfigurationExtensions.WithCookies(configuration);


//

Так как функция WithDefaultLoader представляет функцию расширения
// так как первый параметр помечен как this 
// Что позволяет использовать этот метод через точку
public static IConfiguration WithDefaultLoader(this IConfiguration configuration, Action<LoaderService> setup = null, IEnumerable<IRequester> requesters = null);

 
Кроме того, используются дженерик функции. Я покажу, как с этим бороться.
Но, к сожалению, красивый код на C# превращается в монстра на 1С. Но зато есть примеры, как с этим бороться

//Получить типизированную дженерик функцию
//TElement QuerySelector<TElement>(this IParentNode parent, string selectors) 
Функция ПолучитьДжененрикМетодИнфо(тип,ИмяМетода,типПараметра)
    method = Врап.ТипКакОбъект(тип).GetMethod(ИмяМетода);
    generic = method.MakeGenericMethod(типПараметра);
    return generic;
    
КонецФункции

// Когда есть перегрузка методов нужно искать метод по имени и типам параметров
// Task<IDocument> Navigate<TElement>(this TElement element)
// string Text<T>(this T element)
Функция ПолучитьМетодИнфоОдинДженерикТип(тип,ИмяМетода,типПараметра)
    
    Для Каждого m in Врап.ТипКакОбъект(тип).GetMethods() Цикл
        
        параметры = m.GetParameters();
        if  (m.Name = ИмяМетода)   
            И (параметры.Length = 1)
            И (Врап.ТипКакОбъект(параметры.GetValue(0).ParameterType).IsGenericParameter)
            Тогда
            method = m;
            break;
        КонецЕсли
    КонецЦикла;
    generic = method.MakeGenericMethod(типПараметра);
    return generic;
    
КонецФункции

Функция  ПолучитьМетодИнфо(тип,ИмяМетода)
    method = Врап.ТипКакОбъект(тип).GetMethod(ИмяМетода);
    
    return method;
    
КонецФункции

Функция  ПолучитьПропертиИнфо(тип,ИмяСвойства)
    свойство = Врап.ТипКакОбъект(тип).GetProperty(ИмяСвойства);
    
    return свойство;
    
КонецФункции

Функция ПолучитьМетодИнфо2Параметра(тип,ИмяМетода)
    
    Для Каждого m in Врап.ТипКакОбъект(тип).GetMethods() Цикл
        
        параметры = m.GetParameters();
        if  (m.Name = ИмяМетода)   
            И (параметры.Length = 2)
            Тогда
            method = m;
            break;
        КонецЕсли
    КонецЦикла;
    
    return method;
    
КонецФункции

Функция Получить_SBAppend()
    
    
    Для Каждого m in Врап.ТипКакОбъект(StringBuilder).GetMethods() Цикл
        
        параметры = m.GetParameters();
        if ( (m.Name = "Append")   
            И (параметры.Length = 1) 
            И (Врап.ТипКакОбъект(параметры.GetValue(0).ParameterType).Equals(String)))   
            Тогда
            возврат  m
        КонецЕсли
    КонецЦикла;
    
    возврат Неопределено
КонецФункции

Процедура AngleSharpFormНажатие(Элемент)
    // Вставить содержимое обработчика.
    
    ПутьКСборке="d:\Vs2015Programs\TestScriptingAPI\TestScriptingAPI\bin\Debug\AngleSharp.dll";
    WebsiteUrl = "http://localhost:54361";
    // Получим используемые типы
        AngleSharp_ConfigurationExtensions = Врап.ПолучитьТип("AngleSharp.ConfigurationExtensions");

    BrowsingContext = Врап.ПолучитьТип("AngleSharp.BrowsingContext");
    BrowsingContextExtensions = Врап.ПолучитьТип("AngleSharp.BrowsingContextExtensions");
    ApiExtensions = Врап.ПолучитьТип("AngleSharp.Extensions.ApiExtensions");
    
    // Получим типы нужных интерфейсов
    IHtmlAnchorElement = Врап.ПолучитьТип("AngleSharp.Dom.Html.IHtmlAnchorElement");
    IHtmlFormElement = Врап.ПолучитьТип("AngleSharp.Dom.Html.IHtmlFormElement");
    IElement=Врап.ПолучитьТип("AngleSharp.Dom.IElement");
    
    // Получим типизированные функции    
    QuerySelector_AnchorElement = ПолучитьДжененрикМетодИнфо(ApiExtensions, "QuerySelector",IHtmlAnchorElement);
    QuerySelector_FormElement =   ПолучитьДжененрикМетодИнфо(ApiExtensions, "QuerySelector",IHtmlFormElement);
    
    ApiExtensions_Navigate=ПолучитьМетодИнфоОдинДженерикТип(ApiExtensions,"Navigate",IHtmlAnchorElement);
    ApiExtensions_Text= ПолучитьМетодИнфоОдинДженерикТип(ApiExtensions,"Text",IElement);
    
    configuration = Configuration.Default;
    
    configuration = AngleSharp_ConfigurationExtensions.WithDefaultLoader(configuration);
    configuration = AngleSharp_ConfigurationExtensions.WithCookies(configuration);
    
    context = BrowsingContext.New(configuration);
    
    // Загрузим начальную страницу
    BrowsingContextExtensions.OpenAsync(context, WebsiteUrl).Wait();
    doc = context.Active;
    
    // Получим ссылку содержащий адрес страницы для авторизации
    //<a class="log-in" href="/Home/LogIn">log in here</a>
    
    HtmlAnchorElement = Врап.MethodInfo_Invoke(QuerySelector_AnchorElement,Неопределено,doc, "a.log-in");
    //  var HtmlAnchorElement = AngleSharp.Extensions.ApiExtensions.QuerySelector<AngleSharp.Dom.Html.IHtmlAnchorElement>(doc, "a.log-in");
    // И перейдем на страницу авторизации
    //  doc = ApiExtensions.Navigate(HtmlAnchorElement).Result;
    
    doc = Врап.MethodInfo_Invoke(ApiExtensions_Navigate,Неопределено,HtmlAnchorElement).Result;
    
    
    //  doc = context.Active;
    
    // Получим форму
    //скрытый элемент для верификации который нужно отправить
    //<input name="__RequestVerificationToken" type="hidden" value="2Y-sFIY9JBZc6wc7antGFsBPG1GoiYCbVDtS0khv3JRkcG8CuN69pS3tAZrSiTevGkBjzpTF9AnuK8tZEUrjqn4qB_lbF4dVxsQBubYZkck1">
    HtmlFormElement = Врап.MethodInfo_Invoke(QuerySelector_FormElement,Неопределено,doc, "form");
    
    //   var HtmlFormElement = AngleSharp.Extensions.ApiExtensions.QuerySelector<AngleSharp.Dom.Html.IHtmlFormElement>(doc, "form");
    
    d = Врап.СоздатьОбъект(Dictionary);
    d.Add("User", "User");
    d.Add("Password", "secret");
    // Авторизуемся установив нужные поля и отправим Post запрос на сервер
    ApiExtensions.Submit(HtmlFormElement, d).Wait();
    
    
    doc = context.Active;
    
    // получим ссылку на искомую страницу
    //<a class="secret-link" href="/Home/Secret">our secret</a>
    HtmlAnchorElement = Врап.MethodInfo_Invoke(QuerySelector_AnchorElement,null, doc, "a.secret-link");
    // HtmlAnchorElement = AngleSharp.Extensions.ApiExtensions.QuerySelector<AngleSharp.Dom.Html.IHtmlAnchorElement>(doc, "a.secret-link");
    
    // Перейдем по ссылке
    // doc = ApiExtensions.Navigate(HtmlAnchorElement).Result;
    doc = Врап.MethodInfo_Invoke(ApiExtensions_Navigate,null,HtmlAnchorElement).Result;
    // В первом селекторе параграфе лежит искомая строка
    //<p>The answer to everything is <span id="secret">42</span>.</p>
    селектор=doc.QuerySelector("p");
    резулт = Врап.MethodInfo_Invoke(ApiExtensions_Text,null,селектор);
    //  резулт =The answer to everything is 42
    Сообщить(резулт);
КонецПроцедуры

В шапке статьи есть ссылка на предыдущюю статью Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux

Которая в свою очередь ссылается на Кроссплатформенное использование классов .Net из неуправляемого кода. Или аналог IDispatch на Linux
И там подробно описано, что как и почему.
Так как из Native ВК возвращается закодированная строка например ёЁ<Ьъ>№_%)Э?&2
//Физически это строка ёЁ<Ьъ>№_%)Э?&2 содержащее 12 символов для отделения их от других строк
//и индекс в спике исполуемых объектов на стороне .Net

То есть СборкаAngleSharp.GetType() вернет не объект а строку.

Мне нужно немного времени, чтобы разобраться — заинтересовало
Вы что с гор спустились. Не разу не видели кириллицу? Есть нормально.
Еще раз читайте про синонимы. Я их не зря ввел.
Синонимы надо на русские названия делать(заменяя английскими) :)
Там как раз есть пример.

РасширенияДляТестовый=ъ(СборкаТестовый.Тип("TestDllForCoreClr.РасширенияДляТестовый"));
    Врап.ДобавитьСиноним(РасширенияДляТестовый.ПолучитьСсылку(),"GetStringFromExtensionWithParams","ПолучитьСтрокуИзРасширенияСпарам");

   // Вызовем по оригигальному названию
    Сообщить(Тест.ПолучитьСтрокуИзРасширенияСпарам("Привет"));
   // Вызовем по синониму
    Сообщить(Тест.GetStringFromExtensionWithParams("Привет из GetStringFromExtensionWithParams"));


То есть все в твоих руках. Хочешь по англицки то пиши по англицки, хочешь на русском пиши по русском.
На вкус и цвет товарищей нет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории