自定义MSBuild任务取决于编译后的代码,但还会生成依赖于以下代码的代码 - c#

我试图生成一个C#代码文件,该文件基于XML文件构造一个对象树。 XML中的元素引用正在编译的项目中定义的类型。生成的代码需要构造一个类型的对象树,该对象树在正在编译的项目中找到。为了进一步使事情复杂化,需要将生成的代码编译到正在编译的项目中,并由正在编译的当前项目中的代码引用。

我目前正在尝试使用自定义MSBuild任务来执行此操作。该任务将分发给其他开发人员以在他们自己的项目中使用,因此我无法将可用的类型硬编码到任务中。

这是一些示例代码来说明我在做什么:

// This is not generated
public class SomeClass {

    public void DoSomething() {}

    public string SomeProperty { get; set; }
}

SomeClass是在项目的未生成代码中定义的Type。这是引用SomeClass并填充SomeProperty属性的XML文件:

... bunch of XML...
<SomeClass SomeProperty="SomeValue" />
... bunch more XML...

SomeOtherClass具有未生成的部分声明:

// This is not generated
public partial class SomeOtherClass {

    public void SomeMethod() {
        someField.DoSomething();
    }
}

任务创建部分SomeOtherClass声明:

// This is generated
public partial class SomeOtherClass {

    private SomeClass someField = new SomeClass() {
        SomeProperty = "SomeValue"
    };
}

我认为这看起来很像WPF对XAML文件所做的事情,并且我的用法与之相关(使用XML生成代码,该代码根据正在编译的同一项目中的类型来实例化对象树)。

解决此问题的最佳方法是什么?我应该在任务中进行多阶段编译和使用中间文件吗?我是否应该尝试在Task中单独构建一个临时程序集而不生成代码,然后在临时程序集上进行反射,然后生成代码文件,然后继续正常的构建过程?

c#大神给出的解决方案

这个问题太含糊,无法确定是否有帮助,但希望有帮助。

1.正确获取.props和.targets文件

配置LoadTimeSensitiveTargetsLoadTimeSensitiveProperties以确保IntelliSense甚至在构建项目之前就可以工作。
https://github.com/antlr/antlrcs/blob/9ee43ed9486e55afcc1db06f9f0755658974f99f/AntlrBuildTask/Antlr3.targets#L36-L45
使用AvailableItemName属性可确保用户可以将XML文件的“生成操作”设置为您的自定义项目类型。
https://github.com/antlr/antlrcs/blob/9ee43ed9486e55afcc1db06f9f0755658974f99f/AntlrBuildTask/Antlr3.targets#L75-L79
如有必要,请使用ItemDefinitionGroup元素为具有此自定义项目类型的对象定义默认属性,以减少用户为XML文件配置构建所需的工作量。
https://github.com/antlr/antlrcs/blob/9ee43ed9486e55afcc1db06f9f0755658974f99f/AntlrBuildTask/Antlr3.targets#L81-L88
请密切注意将项目添加到诸如_GeneratedCodeFiles之类的集合中的方式,以确保“清理”目标可以正确清理您的构建。
使用.props文件指定默认配置元素。创建用于分发的NuGet包时,.props文件将包含在用户项目的顶部,而.targets将包含在项目的底部。

2.不要在代码生成过程中执行不必要的验证

C#编译器会在用户输入错误时通知您(例如,引用项目中不存在的项目)。通过在代码生成步骤中避免这种分析,可以避免问题中描述的循环依赖性。

3.禁用或卸载ReSharper

ReSharper不支持在构建过程中生成代码的扩展。尽管上述说明多年来一直特别遵循XAML支持建立的模式,但您仍然会选择以下选择:

保留安装ReSharper,但不对生成的代码提供IntelliSense支持。
卸载ReSharper,从打开解决方案的第一刻开始,让Visual Studio为您的自定义项目类型提供与XAML文件相同的全新IntelliSense体验。

4.例子

这是在构建过程中生成代码的两个扩展。

ANTLR 3:
https://github.com/antlr/antlrcs/blob/9ee43ed9486e55afcc1db06f9f0755658974f99f/AntlrBuildTask/Antlr3.props
https://github.com/antlr/antlrcs/blob/9ee43ed9486e55afcc1db06f9f0755658974f99f/AntlrBuildTask/Antlr3.targets

ANTLR 4:
https://github.com/tunnelvisionlabs/antlr4cs/blob/9ee43ed9486e55afcc1db06f9f0755658974f99f/runtime/CSharp/Antlr4BuildTasks/Antlr4.v4.0.props
https://github.com/tunnelvisionlabs/antlr4cs/blob/9ee43ed9486e55afcc1db06f9f0755658974f99f/runtime/CSharp/Antlr4BuildTasks/Antlr4.v4.0.targets

LeetCode题解计算机为什么是基于二进制的?

可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制

LeetCode题解深度优先遍历和回溯的关系?

深度优先遍历的范围更大还是回溯的范围更大?为什么?题解:我的理解是:dfs是回溯思想的一种体现- 回溯:是在整个搜索空间中搜索出可行解,在搜索过程中不断剪枝回退,这是回溯的思想,这个搜索空间并没有限制于特定的数据结构。- dfs:dfs是指特定的数据结构中如图,树(特殊的图)中搜索答案,范围限制在了特定的数据结构。个人拙见。

LeetCode题解盲人买袜子。

他们都各自买了两对黑袜和两对白袜,八对袜子的布质、大小完全相同,而每对袜子都有一张商标纸连着。两位盲人不小心将八对袜子混在一起。他们每人怎样才能取回黑袜和白袜各两对呢?题解:暴力破解, 把袜子都拆开 一人一只 哈哈

LeetCode题解白石搭白塔

输入黑块和白块的数量,用输入的方块数目建塔,输出最大高度和种数,两种方法至少一层颜色不同才能算不同的方法塔满足下列要求:1. 塔底层块数和高度数值相同,逐层递减1,最高层为12. 每层颜色相同

LeetCode题解分鸡块

外卖鸡块分别有 4,6,12 块, 每 固定块数不能分开装, 用户给一个数字, 要求返回满足用户订单(可以等于也可以大于)的最少的盒数的组合