Кроссплатформенное использование классов .Net в 1С через Native ВК. Или замена COM на Linux II

  • Tutorial
Это продолжение статей:

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

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 18

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

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

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

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

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

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


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


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

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


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

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


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


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

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

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

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

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

                        0
                        Мне нужно немного времени, чтобы разобраться — заинтересовало
              0
              НачатьКомментарий
              ПечатьТекст РусскийЯзыкСмешатьСАнглийскийЯзык Аз ЕсмьЗло
              КонецКомментарий
              

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

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


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

              Only users with full accounts can post comments. Log in, please.