Visual Studio + Roslyn = 1Cのコンフィギュレーター:エンタープライズ

Roslynを使用すると、C#プロジェクトを1CのオープンXML形式に変換できます:エンタープライズ構成。 Visual StudioでサポートされるC#-projectには、Intellisense、インタラクティブな構文と型チェック、リファクタリング、高度なプロジェクト検索、XmlDocサポートが自動的に提供されます。 ディスク上のプロジェクトドキュメントのカスタマイズ可能な配置と、より表現力豊かで経済的な形式により、Visual StudioのC#プロジェクトがバージョン管理システムで最適な選択肢になります。



純粋な理論から1Cのすべての機能の実装までは非常に遠いことは明らかです。 この記事の例には、次の制限があります。 この例では、いくつかのタイプのオブジェクトと頻繁に発生するいくつかのプロパティのサポートを実装しています。 1Cでは複合型を使用できますが、オブジェクトの属性は同じ型にすることができます。 1Cコードへのコード変換はサポートされていません。 英語名で実装されています。







1C構成XMLアップロード





バージョン8.3 1C以降、オープンXML形式との間で構成をアップロード/ダウンロードする方法を学びました。 彼女はこれを独自の方法で行います。 たとえば、UT 11.0.7のアンロードには約6分かかります。 この場合、すべての構成ファイルは単一のディレクトリにダンプされます。 ファイルのサイズは約430 MBで約10K(万)です。 このようなアンロードは、オープンの分野では大きな成果と見なされます。これは、以前は構成が閉じたcf-formatにパックされていたためです。



これはXML Language.Russian.xmlファイルの1つです



<?xml version="1.0" encoding="UTF-8"?> <MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Language uuid="7a630662-cf14-44d7-a01c-08006bb5bffa"> <Properties> <Name></Name> <Synonym/> <Comment/> <LanguageCode>ru</LanguageCode> </Properties> </Language> </MetaDataObject>
      
      







XML構成体をC#定義で置き換える





C#プロジェクトでは、クラスが各1Cオブジェクトを担当します。 これがディレクトリの場合、クラスはCatalogクラスを継承し、列挙はEnumクラスを継承します。 オブジェクトと属性のプロパティは、C#-attributesで示されます。



その結果、ロシア語のXML定義はRussian.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 <table part row>として定義されます



 [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<> ;
      
      







オブジェクトモジュールとマネージャーモジュールのイベントは、オーバーライドメソッドとして実装されます。 これらは次のようになります。



 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(); }
      
      







メソッドは現在1Cコードに変換されていないことに注意してください。 1Cプリプロセッサのディレクティブをどう処理するか、およびメイン1Cオブジェクトの多重継承が必要かどうかは不明のままです。 C#での関数呼び出しはクラスと組み合わせてのみ実行できるため、Gはグローバルコンテキストを表します。



CSPROJプロジェクトのコンパイル





以前の記事habrahabr.ru/post/245453で、単一のCSファイルをコンパイルする機能について説明しました。 多くの場合、プロジェクト全体-複数のファイルをコンパイルする必要があります。



Roslynには、slnソリューションとVisual Studio csprojプロジェクトを処理するための組み込みクラスがあります。 問題は、MSBuildツールに同梱されている個々のアセンブリを参照していることです。 Roslynの最新バージョンは、MSBuild Tools 2014のビルドを指し、個別にダウンロードすることはできません。 現在、インストールはVisual Studio 14 CTPディストリビューションの一部です。



.NetフレームワークにはアセンブリMicrosoft.Build.dll v.4が含まれていることがわかりました。 C#プロジェクトファイルを読み取るための実装があります。 このアセンブリをRoslynロジックと独立してドッキングし、MSBuildツールから分離できます。 実装は次のようになります。



 var project = new Project(projectFilePath); List<string> references = new List<string>(); List<SyntaxTree> trees = new List<SyntaxTree>(); foreach(var item in project.Items) { if (item.ItemType == "Reference") { references.Add(item.EvaluatedInclude); } else if (item.ItemType == "Compile") { string filePathToCompile = System.IO.Path.Combine(project.DirectoryPath, item.EvaluatedInclude); var text = System.IO.File.ReadAllText(filePathToCompile); trees.Add(CSharpSyntaxTree.ParseText(text)); } } var assemblyName = project.GetProperty("AssemblyName").EvaluatedValue; var compilation = CSharpCompilation.Create(assemblyName) .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)) .AddReferences(new MetadataFileReference(typeof(Elisy.Configuration.Configuration).Assembly.Location)) .AddReferences(new MetadataFileReference(typeof(object).Assembly.Location)) .AddSyntaxTrees(trees.ToArray());
      
      







さらにプロジェクトプロパティを実装する必要がある場合は、Roslynプロジェクトでそれら確認できます



1Cと互換性のあるXMLファイルの取得:エンタープライズ





XMLファイルを生成する場合、ほとんどの作業は型、そのメンバー、および属性を使用して行われます。 Roslyn CSharpCompilationのオブジェクトの資金は非常に限られていることが判明しました。 それらを介してSystem.Type型に到達することは不可能であり、継承を考慮して属性のリストを取得することは不可能です。 したがって、完全な分析を行うには、Roslynツールを使用してアセンブリを作成し、Reflection分析用にロードする方が適切です。



 MemoryStream ms = new MemoryStream(); compilation.Emit(ms); var assembly = Assembly.Load(ms.ToArray());
      
      







「api-ms-win-core-l1-2-0.dllが見つかりません」というエラーが原因で、ReflectionOnlyLoadとしてのアセンブリのロードに失敗したのは奇妙です。 アセンブリに含まれる型を読み取ろうとしているときにエラーが発生しました。 ただし、アセンブリは通常どおり読み込まれ、通常のLoad呼び出しで機能します。



XMLファイルの生成は、構成およびメインオブジェクトから継承されたすべてのタイプの列挙、オブジェクトおよび属性のプロパティの列挙に要約されます。



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)));
      
      







1Cは多くのタグがないことに忠実であり、それらをデフォルト値に置き換えることがわかりました。 したがって、XMLファイルの空の値をスキップして、占有ディスク容量を削減できます。 節約額は非常に大きくなる可能性があります(最大40%)。 XMLの代わりにcsファイルを使用すると、スペースをさらに節約できます(最大60%)。



結論





Visual Studioを使用すると、理論的には代替の1Cコンフィギュレーターを作成できます。 アイデアをさらに促進するには、すべての主要オブジェクト、フォームストレージ、1CでのC#言語の翻訳、1Cプリプロセッサディレクティブ、通常のレイアウト、ACSレイアウトに同意する必要があります。



1Cからの現在のXMLアップロードは、すべてのファイルが単一のディレクトリに収集されるため、分析には不便です。



現在の1C XMLアップロードは冗長であり、データ損失なしにそのサイズを最大40%削減できます。また、C#の形式でソースコードを保存すると、ディスク容量を最大60%節約できます。



Roslyn組み込みツールを使用したVisual Studioのcsprojプロジェクトとslnソリューションの読み取りは、MSBuild Tools 2014の入手が難しいため簡単ではありません。.NetFramework 4クラスとRoslyn自身の初期化で補正できるようになりました。



Elisy.Configuration.zip(2,19 mb)



All Articles