共享项目中如何配置Conditional DependentUpon实现正确文件分组
如何在共享项目(.shproj)中配置平台专属文件的正确分组结构
问题背景
我有一个面向多平台的共享项目(.shproj),包含普通C#类和XAML标记文件,部分文件是特定平台专属的(如*.Android.cs)。期望实现的分组规则是:
- 普通C#类的平台专属.cs文件(如
Class.Android.cs),分组在对应的主Class.cs文件下 - XAML标记文件的平台专属.cs文件(如
Page.Android.cs),分组在对应的Page.xaml文件下
当前使用的MSBuild配置如下:
<Compile Update="**\*Android.cs"> <DependentUpon>$([System.String]::Copy(%(Filename)).Replace('.Android', '.xaml'))</DependentUpon> </Compile> <Compile Update="**\*Android.cs"> <DependentUpon>$([System.String]::Copy(%(Filename)).Replace('.Android', '.cs'))</DependentUpon> </Compile>
同时在.projitems文件中,已显式配置XAML代码隐藏文件的依赖关系:
<Compile Include="$(MSBuildThisFileDirectory)Pages\SomePage.xaml.cs"> <DependentUpon>SomePage.xaml</DependentUpon> </Compile>
当前配置导致分组结构不符合预期:
- Page.xaml - Page.cs - Page.Android.cs - Page.xaml.cs
而期望的正确结构是:
- Page.xaml - Page.cs - Page.Android.cs - Page.xaml.cs - Class.cs - Class.Android.cs
解决方案
问题出在当前的两个Compile Update节点未区分场景,会同时作用于所有*.Android.cs文件,最终后一个配置会覆盖前一个的DependentUpon值。我们需要通过MSBuild条件判断,为两种场景分别配置依赖关系:
修改后的MSBuild配置
<!-- 当存在对应XAML文件时,将平台专属.cs文件挂到XAML下 --> <Compile Update="**\*Android.cs" Condition="Exists('$(MSBuildProjectDirectory)\$([System.String]::Copy(%(Filename)).Replace('.Android', '.xaml'))')"> <DependentUpon>$([System.String]::Copy(%(Filename)).Replace('.Android', '.xaml'))</DependentUpon> </Compile> <!-- 当不存在对应XAML文件时,将平台专属.cs文件挂到主C#类文件下 --> <Compile Update="**\*Android.cs" Condition="!Exists('$(MSBuildProjectDirectory)\$([System.String]::Copy(%(Filename)).Replace('.Android', '.xaml'))')"> <DependentUpon>$([System.String]::Copy(%(Filename)).Replace('.Android', '.cs'))</DependentUpon> </Compile>
配置说明
- 条件判断逻辑:
- 第一个配置通过
Exists()函数检查,是否存在与平台文件同名(去掉.Android后缀)的XAML文件。如果存在,就将该平台文件的依赖项设为对应的XAML文件 - 第二个配置则针对没有对应XAML文件的平台文件,将其依赖项设为主C#类文件(去掉
.Android后缀的.cs文件)
- 第一个配置通过
- 原有
.projitems中关于.xaml.cs的配置无需修改,它会继续保持Page.xaml.cs挂在Page.xaml下的结构 - 这种条件配置会确保每个
*.Android.cs文件只会匹配其中一个规则,不会出现覆盖问题
内容的提问来源于stack exchange,提问作者Beltway
相关产品推荐
相关产品推荐

