如何在编译时基于MAUI项目XML文件在类库生成同步C#类?
可行实现方案及代码片段
方案1:MSBuild任务+自定义代码生成逻辑
核心逻辑:通过MAUI项目的MSBuild任务触发代码生成,将生成的C#类直接写入功能类库目录,类库编译时自动包含该文件。
步骤与代码
- 封装XML转C#的生成逻辑(复用你现有代码,放在功能类库中)
using System.Xml; using System.Text; using System.IO; namespace YourFeatureLibrary.Utils; public static class XmlToClassGenerator { public static void GenerateSettingsClass(string xmlPath, string outputFile) { // 解析XML文件(示例结构:<keys><key name="key1" type="string"/></keys>) var doc = new XmlDocument(); doc.Load(xmlPath); var keyNodes = doc.SelectNodes("//key")?.Cast<XmlNode>().ToList() ?? []; // 拼接C#类代码 var codeBuilder = new StringBuilder(); codeBuilder.AppendLine("namespace YourFeatureLibrary.Generated;"); codeBuilder.AppendLine("public class AppSettings"); codeBuilder.AppendLine("{"); foreach (var node in keyNodes) { var keyName = node.Attributes?["name"]?.Value; var type = node.Attributes?["type"]?.Value ?? "string"; if (string.IsNullOrEmpty(keyName)) continue; codeBuilder.AppendLine($" public {type} {keyName} {{ get; set; }}"); } codeBuilder.AppendLine("}"); // 确保输出目录存在并写入文件 Directory.CreateDirectory(Path.GetDirectoryName(outputFile)!); File.WriteAllText(outputFile, codeBuilder.ToString()); } }
- MAUI项目中添加MSBuild触发任务
修改MAUI项目的.csproj,添加编译前执行的任务:
<Target Name="GenerateSettingsClass" BeforeTargets="Build"> <PropertyGroup> <!-- 你的XML文件路径 --> <XmlSettingsPath>$(ProjectDir)Configs\AppSettings.xml</XmlSettingsPath> <!-- 生成文件输出到功能类库的Generated目录 --> <GeneratedClassPath>$(SolutionDir)YourFeatureLibrary\Generated\AppSettings.cs</GeneratedClassPath> </PropertyGroup> <!-- 调用代码生成逻辑 --> <UsingTask TaskName="GenerateSettings" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll"> <ParameterGroup> <XmlPath ParameterType="System.String" Required="true" /> <OutputPath ParameterType="System.String" Required="true" /> </ParameterGroup> <Task> <Using Namespace="System" /> <Using Namespace="YourFeatureLibrary.Utils" /> <Code Type="Fragment" Language="cs"> <![CDATA[ XmlToClassGenerator.GenerateSettingsClass(XmlPath, OutputPath); ]]> </Code> </Task> </UsingTask> <GenerateSettings XmlPath="$(XmlSettingsPath)" OutputPath="$(GeneratedClassPath)" /> </Target>
- 功能类库配置包含生成文件
修改功能类库的.csproj,确保生成的文件被编译:
<ItemGroup> <Compile Include="Generated\**\*.cs" /> </ItemGroup> <!-- 标记为自动生成文件,避免误修改 --> <ItemGroup> <None Include="Generated\**\*.cs" DependentUpon="AppSettings.xml" /> </ItemGroup>
方案2:调整Source Generator引用方式
核心逻辑:将Source Generator放在功能类库中,通过MSBuild属性传递MAUI项目的XML路径,让生成的代码归属到功能类库。
步骤与代码
- 编写Source Generator(创建.NET Standard 2.0类库,引用
Microsoft.CodeAnalysis.Analyzers和Microsoft.CodeAnalysis.CSharp)
using Microsoft.CodeAnalysis; using System.Xml; using System.Text; using System.IO; [Generator] public class SettingsGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { } public void Execute(GeneratorExecutionContext context) { // 获取MAUI项目传递的XML路径 if (!context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.XmlSettingsPath", out var xmlPath) || !File.Exists(xmlPath)) { context.ReportDiagnostic(Diagnostic.Create( new DiagnosticDescriptor("XML001", "XML路径错误", "未找到指定的XML配置文件", "Generator", DiagnosticSeverity.Error, true), Location.None)); return; } // 解析XML并生成类(逻辑同方案1) var doc = new XmlDocument(); doc.Load(xmlPath); var keyNodes = doc.SelectNodes("//key")?.Cast<XmlNode>().ToList() ?? []; var codeBuilder = new StringBuilder(); codeBuilder.AppendLine("namespace YourFeatureLibrary.Generated;"); codeBuilder.AppendLine("public class AppSettings"); codeBuilder.AppendLine("{"); foreach (var node in keyNodes) { var keyName = node.Attributes?["name"]?.Value; var type = node.Attributes?["type"]?.Value ?? "string"; if (string.IsNullOrEmpty(keyName)) continue; codeBuilder.AppendLine($" public {type} {keyName} {{ get; set; }}"); } codeBuilder.AppendLine("}"); // 将生成代码添加到类库编译上下文 context.AddSource("AppSettings.g.cs", codeBuilder.ToString()); } }
- 配置项目引用
- 功能类库的
.csproj引用Source Generator项目:
<ItemGroup> <ProjectReference Include="..\SettingsGenerator\SettingsGenerator.csproj" PrivateAssets="all" /> </ItemGroup>
- MAUI项目的
.csproj引用功能类库并传递XML路径:
<ItemGroup> <ProjectReference Include="..\YourFeatureLibrary\YourFeatureLibrary.csproj"> <PrivateAssets>none</PrivateAssets> </ProjectReference> </ItemGroup> <PropertyGroup> <XmlSettingsPath>$(ProjectDir)Configs\AppSettings.xml</XmlSettingsPath> </PropertyGroup> <!-- 让Source Generator能读取到该属性 --> <ItemGroup> <CompilerVisibleProperty Include="XmlSettingsPath" /> </ItemGroup>
注意事项
- 方案1更适合已有成熟XML转C#逻辑的场景,配置简单;方案2更贴合.NET现代编译时代码生成的设计。
- 所有路径尽量使用MSBuild预定义属性(如
$(SolutionDir)、$(ProjectDir)),避免硬编码绝对路径。
内容的提问来源于stack exchange,提问作者Prabhav Mehra
相关产品推荐
相关产品推荐

