Visual Studio + Roslyn = конфигуратор для 1С: Предприятие
Roslyn позволяет C# проект преобразовать в открытый XML-формат конфигурации 1С: Предприятие. C#-проект при поддержке Visual Studio автоматически снабжается Intellisense, интерактивной проверкой синтаксиса и типов, рефакторингом, расширенным поиском по проекту, поддержкой XmlDoc. Настраиваемое расположение документов проекта на диске и более выразительный и экономный формат делает C#-проект на Visual Studio лучшим выбором в системах версионирования.Понятно, что от чистой теории до реализации всех особенностей 1С очень далеко. Приведенный в статье пример обладает следующими ограничениями. В примере реализована поддержка нескольких типов объектов и нескольких часто встречающихся свойств. Атрибуты объектов могут быть одного типа, хотя 1С допускает составной тип. Трансляция кода в код 1С не поддерживается. Реализованы англоязычные наименования.
XML-выгрузка конфигурации 1СНачиная с версии 8.3 1С научилась выгружать/загружать конфигурацию в/из открытый формат XML. Делает она это в своей самобытной манере. Выгрузка, например, УТ 11.0.7 займет примерно 6 минут. При этом все файлы конфигурации будут свалены в единый каталог. Файлов будет около 10K (десяти тысяч) размером примерно 430 Мбайт. Такая выгрузка считается огромным достижением в области открытости, потому что ранее конфигурация запаковывалась в закрытый cf-формат, распознать который можно было только специализированными средствами: через .Net-совместимый cfProject или v8unpack.
Так выглядит один из файлов XML Language.Русский.xml
В результате XML-определение язык Русский примет такой вид Русский.cs
using System; using Elisy.Configuration.DataAnnotations; using Elisy.Configuration; namespace Test.Languages { [Uuid (»7a630662-cf14–44d7-a01c-08006bb5bffa»)] [LanguageCode («ru»)] public class Русский : Language { } } Ссылки на объекты определяются через типы вида CatalogRef<>. Например, так
[Uuid («e140b824-c8f9–4155–87e6-d408e73ccc69»)] [Synonym («ru», «Рубрика»)] public CatalogRef<рубрики> Рубрика; Табличная часть определяется как TabularSection<строкатабличнойчасти>
[Uuid («bb2c088e-8fb3–4469-abd7-ba6b4104ae88»)] [GeneratedTypeAttribute (GeneratedTypeCategory.TabularSection,»8ef1c35e-8b55–488f-8e24–61f73d287458», «b300dc36-fe12–41d5-a462–792716a1e508»)] [GeneratedTypeAttribute (GeneratedTypeCategory.TabularSectionRow,»92e3cead-a61b-474c-8515–56e4911339c7», «dfa007ab-4185–443f-8d11-f7468a7c195e»)] [Synonym («ru», «Рубрики»)] public TabularSection<РубрикаИзображения> Рубрики; События модуля объекта и модуля менеджера реализуются как override-методы. Могут выглядеть так:
public override void BeforeWrite (ref bool cancel) { var ДубликатПоНаименованию = Catalog.FindByDescription<Изображения>(Description, true); if (! IsFolder && IsNew () && G.ValueIsFilled (ДубликатПоНаименованию)) { G.Message («Найден дубликат изображения с наименованием:» + Description + ». Запись не производится»); cancel = true; return; } if (! IsFolder) Рубрики.GroupBy («Рубрика»); //Убрать ненужные рубрики, обработанные групповой обработкой var НайденнаяСтрока = Рубрики.Find (Catalogs.Рубрики.УдалитьРубрику, «Рубрика»); if (G.ValueIsFilled (НайденнаяСтрока)) Рубрики.Delete (НайденнаяСтрока); } Следует отметить, что методы сейчас никак не транслируются в код 1С. Не понятным остается, что делать с директивами препроцессора 1С и нужно ли множественное наследование основных объектов 1С. G-обозначает глобальный контекст, так как вызов функций в C# может выполняться только в привязке к классу.
Компилирование проекта CSPROJ В прошлой статье habrahabr.ru/post/245453/ была описана возможность компилирования одного файла CS. Чаще требуется скомпилировать целый проект — несколько файлов.
В Roslyn есть встроенные классы, отвечающие за обработку sln-решений и csproj-проектов Visual Studio. Проблема состоит в том, что они ссылаются на отдельные сборки, поставляемые в составе MSBuild Tools. Последняя версия Roslyn ссылается на сборки MSBuild Tools 2014, которые отдельно скачать не получится. Инсталляция сейчас входит в состав дистрибутива Visual Studio 14 CTP.
Оказалось, что в состав .Net framework входит сборка Microsoft.Build.dll v. 4. В ней есть реализация чтения файла проекта C#. Можно самостоятельно реализовать состыковку этой сборки с логикой Roslyn и получить изоляцию от MSBuild Tools. Реализация будет примерно такой:
var project = new Project (projectFilePath);
List
Получение XML-файлов совместимых с 1С: Предприятие При генерации XML-файлов работа большей частью ведется с типами, их членами и атрибутами. Оказалось, что объекты Roslyn CSharpCompilation очень ограничены в средствах. Через них нельзя выйти на типы System.Type, нельзя получить список атрибутов с учетом наследования. Поэтому для полноценного анализа лучше создать сборку средствами Roslyn и загрузить ее для Reflection-анализа:
MemoryStream ms = new MemoryStream (); compilation.Emit (ms); var assembly = Assembly.Load (ms.ToArray ()); Странно, что не удалось загрузить сборку как ReflectionOnlyLoad из-за ошибки «missing api-ms-win-core-l1–2–0.dll». Ошибка возникала при попытке прочитать входящие в состав сборки типы. Тем не менее, сборка нормально загружается и работает через обычный вызов Load.
Генерация XML-файлов сводится к перебору всех типов, наследованных от Configuration и основных объектов, к перебору свойств объектов и атрибутов.
XML строится средствами XML LINQ, например, так:
XElement configurationElement = new XElement (Compiler.MdClasses + «Language», language.GetUuidXml (), new XElement (Compiler.MdClasses + «Properties», new XElement (Compiler.MdClasses + «Name», language.Name), language.GetSynonimXml (), language.GetCommentXml (), new XElement (Compiler.MdClasses + «LanguageCode», language.GetAttribute ().Value) ) ); var document = CreateMetadataObjectDocument (configurationElement); document.Save (Path.Combine (outFolder, String.Format («Language.{0}.xml», language.Name))); Удалось выяснить, что 1С лояльно относится к отсутствию многих тегов, заменяя их значениями по умолчанию. Поэтому пустые значения в XML-файлах можно пропустить, тем самым сократив занимаемый размер на диске. Размер экономии может быть весьма значительным — до 40 процентов. Использование же cs-файлов вместо XML дает еще большую экономию места — до 60%.
Выводы Средствами Visual Studio теоретически возможно создать альтернативный конфигуратор 1С. Для дальнейшего продвижения идеи нужно принять соглашения относительно всех основных объектов, хранения форм, трансляции языка C# в 1С, директив препроцессора 1С, обычных макетов и макетов СКД;
Текущая XML-выгрузка от 1С неудобна для анализа, потому что все файлы собраны в единый каталог;
Текущая XML-выгрузка 1С избыточна, и ее размер может быть уменьшен без потери данных до 40%, а хранение исходных кодов в виде C# позволит экономить до 60 процентов дискового пространства;
Чтение csproj-проектов и sln-решений Visual Studio встроенными средствами Roslyn непросто реализуемо из-за сложной доступности MSBuild Tools 2014. Компенсировать сейчас можно классами .Net Framework 4 и собственной инициализацией Roslyn.
Elisy.Configuration.zip (2,19 mb)