You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在编译时基于MAUI项目XML文件在类库生成同步C#类?

可行实现方案及代码片段

方案1:MSBuild任务+自定义代码生成逻辑

核心逻辑:通过MAUI项目的MSBuild任务触发代码生成,将生成的C#类直接写入功能类库目录,类库编译时自动包含该文件。

步骤与代码

  1. 封装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());
    }
}
  1. 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>
  1. 功能类库配置包含生成文件
    修改功能类库的.csproj,确保生成的文件被编译:
<ItemGroup>
  <Compile Include="Generated\**\*.cs" />
</ItemGroup>
<!-- 标记为自动生成文件,避免误修改 -->
<ItemGroup>
  <None Include="Generated\**\*.cs" DependentUpon="AppSettings.xml" />
</ItemGroup>

方案2:调整Source Generator引用方式

核心逻辑:将Source Generator放在功能类库中,通过MSBuild属性传递MAUI项目的XML路径,让生成的代码归属到功能类库。

步骤与代码

  1. 编写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());
    }
}
  1. 配置项目引用
  • 功能类库的.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 18:40:41