我正在尝试生成一个C#代码文件,该文件基于XML文件构造对象树。 XML中的元素指的是正在编译的项目中定义的类型。生成的代码需要构建在正在编译的项目中找到的类型的对象树。更复杂的是,生成的代码需要编译到正在编译的项目中,并由当前正在编译的项目中的代码引用。
我目前正在尝试使用自定义MSBuild任务执行此操作。此任务将分发给其他开发人员以用于他们自己的项目,因此我无法将可用的类型硬编码到任务中。
以下是一些示例代码,用于说明我正在做的事情:
// This is not generated
public class SomeClass {
public void DoSomething() {}
public string SomeProperty { get; set; }
}
SomeClass 是在项目中的非生成代码中定义的Type。以下是引用 SomeClass 的XML文件,并填充 SomeProperty 属性:
... 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中进行多阶段编译和使用中间文件吗?我是否应该尝试在没有生成代码的情况下在Task中单独构建临时程序集,然后对临时程序集进行反射,然后生成代码文件,然后允许正常构建过程继续?
答案 0 :(得分:5)
问题太模糊,无法确定这有用,但希望这会有所帮助。
配置LoadTimeSensitiveTargets
和LoadTimeSensitiveProperties
以确保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 将被列入项目的底部。
如果用户犯了错误(例如,引用项目中不存在的项目),C#编译器将通知您。通过在代码生成步骤中避免这种分析,避免了问题中描述的循环依赖。
ReSharper不支持在构建期间生成代码的扩展。尽管上述指令具体遵循XAML支持多年来建立的模式,但您仍将坚持以下选择:
以下是在构建期间生成代码的两个扩展。
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