8

在我们的项目中,我们使用了大量的 T4 代码生成。我们使用一个称为 X-Tensive 的 DataObjects.Net 的 ORM。我们有一点鸡蛋问题。在使用程序集的元数据生成代码之前,我们需要编译 ORM 的类。然后当代码生成时,我们可以再次编译模型,但现在结合生成的代码(部分类)。没有生成的代码,模型类中的大部分自定义代码都无法编译。

我们如何解决它是在 VS2013 中有一个单独的配置,称为“模型”。在此配置中,存在“条件编译符号”调用“JUSTMODEL”。在没有生成代码的情况下无法编译的所有代码都放置在 #if !JUSTMODEL #endif 编译器指令之间,这会导致此代码不会针对“模型”配置进行编译。

这有点乏味。我们创建了一个可扩展性的小应用程序来自动化这个过程,但是运行这些过程变得越来越耗时。

现在我想知道是否可以在不通过某种可扩展性 API 构建程序集的情况下获取模型程序集的元数据。我在 Visual Studio 中看到很多工具可以理解编辑器中加载的类并给我一些反馈(如智能感知)。

4

2 回答 2

7

还有比 NRefactor 更好的方法。我在 Visual Studio 中发现了 CodeModel。它为我提供了生成代码所需的所有元数据。您可以在网上找到很多关于如何实现这一目标的详细信息,如下所示:

  1. 微软
  2. 有形

和许多其他地方。由于数据的动态特性,编码与 C# 中的编码有些不同,但是当您掌握它的窍门时,它非常简单且非常强大。

于 2014-03-25T07:13:29.733 回答
2

我会考虑使用NRefactory库或类似的库。NRefactory 的想法类似于 Roslyn,所以应该可以解决您的问题。如果我对您的理解正确,您需要在编译之前了解有关类及其成员的信息。基于 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 )
    {
        //...
    }
}

此示例仅执行源代码的语法分析。但是,您也可以使用CSharpAstResolver类使用 NRefactory执行语义分析。

于 2014-03-23T15:10:27.227 回答