简体   繁体   English

如何在不编译项目的情况下获取类的元数据

[英]How to get metadata of classes without compiling the project

In our project we use a lot of T4 code generation. 在我们的项目中,我们使用了大量的T4代码生成。 We use an ORM called DataObjects.Net of X-Tensive. 我们使用一个名为DataObjects.Net的X-Tensive ORM。 We have a bit a chicken-egg problem. 我们有点鸡蛋问题。 We need to compile the classes of the ORM before we can use the assembly's metadata to generate code. 在我们使用程序集的元数据生成代码之前,我们需要编译ORM的类。 Then when the code is generated we can compile the model again but now in combination with generated code (partial classes). 然后,当生成代码时,我们可以再次编译模型,但现在与生成的代码(部分类)组合。 Most of the custom code in the model classes can not be compiled without the generated code. 如果没有生成的代码,则无法编译模型类中的大多数自定义代码。

How we solved it is to have a separate configuration in VS2013 called 'Model'. 我们如何解决它是在VS2013中有一个名为“模型”的单独配置。 In this configuration a 'Conditional compilation symbol' call 'JUSTMODEL' is present. 在此配置中,存在“条件编译符号”调用“JUSTMODEL”。 All code that does not compile without the generated code is placed between #if !JUSTMODEL #endif compiler directives which causes this code not be compiled for the 'Model' configuration. 在没有生成代码的情况下不编译的所有代码都放在#if!JUSTMODEL #endif编译器指令之间,这导致不为“模型”配置编译此代码。

This is a bit tedious. 这有点单调乏味。 We have created a little extensiblity application that automates this proces but it more and more becomes pretty time consuming to run the proces. 我们已经创建了一个可扩展的应用程序来自动执行此过程,但运行过程会越来越耗费时间。

Now I was wondering if it is possible to get the metadata of the Model assembly without building the assembly via an extensibility API of some kind. 现在我想知道是否有可能获得Model程序集的元数据而不通过某种扩展性API构建程序集。 I see lots of tools in Visual Studio that understand classes loaded in the editors and give me some feedback (like intellisense). 我在Visual Studio中看到很多工具,它们理解编辑器中加载的类并给我一些反馈(比如intellisense)。

There is an even better way than NRefactor. 有比NRefactor更好的方法。 I've discovered the CodeModel inside Visual Studio. 我在Visual Studio中发现了CodeModel。 It gives me all the metadata I need to generate our code. 它为我提供了生成代码所需的所有元数据。 You can find a lot of details on how to achieve that on the net like here: 你可以在这里找到很多关于如何在网上实现这一点的细节:

  1. Microsoft 微软
  2. Tangible 有形

and many other places. 和许多其他地方。 The coding is a bit different than in C# because of the dynamic nature of the data but when you get the hang of it, it's quite easy and very powerfull. 由于数据的动态特性,编码与C#有点不同,但当你掌握它时,它非常容易且非常强大。

I would consider using NRefactory library or similar. 我会考虑使用NRefactory库或类似的。 The idea of NRefactory is similar to Roslyn so should solve you problem. NRefactory的想法与Roslyn类似,所以应该解决你的问题。 If I understand you correctly you need information about classes and their members before compilation. 如果我理解正确,您需要在编译之前获得有关课程及其成员的信息。 The simplest code based on NRefactory, responsible for retrieving list of classes together with information about methods and properties, could look in the following way: 基于NRefactory的最简单的代码,负责检索类的列表以及有关方法和属性的信息,可以通过以下方式查找:

var parser = new CSharpParser();
var syntaxTree = parser.Parse(code);

var classes = syntaxTree.Descendants.OfType<TypeDeclaration>().Where(x => x.ClassType == ClassType.Class);
foreach (var typeDeclaration in classes)
{
    var result = typeDeclaration.Descendants.Where(d => d is MethodDeclaration || d is PropertyDeclaration);
    foreach (var declaration in result )
    {
        //...
    }
}

This example performs only syntax analysis of the source code. 此示例仅执行源代码的语法分析。 However, you can also perform semantic analysis with NRefactory by using CSharpAstResolver class. 但是,您也可以使用CSharpAstResolver类使用NRefactory执行语义分析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM