Search code examples
visual-studioxamarinvisual-studio-mac

How to set an Embedded Resource property with VS Build Configurations?


I'm using Visual Studio for Mac.

I found this https://forums.xamarin.com/discussion/96777/how-to-set-info-plist-properties-with-vs-build-configurations which describes how you can setup a secondary plist files with a specific build configuration. Which works well..

<None Include="Entitlements.plist" Condition="'$(Configuration)' != 'Debug-Staging'" />
<None Include="Entitlements-staging.plist" Condition="'$(Configuration)' == 'Debug-Staging'">
  <LogicalName>Entitlements.plist</LogicalName>
</None>

However this approach doesn't work with Embedded Resources...

<EmbeddedResource Include="ClientResources\myfolder\config.json" 
         Condition="'$(Configuration)' != 'Debug-Staging'" />
<EmbeddedResource Include="ClientResources\myfolder\config-staging.json" 
           Condition="'$(Configuration)' == 'Debug-Staging'">
    <LogicalName>config.json</LogicalName>
</EmbeddedResource>

I've also tried the LogicalName with the full path... Also putting the condition on ItemGroup instead doesn't help.

Edit:

Here's a sample project I created... https://github.com/JulesMoorhouse/ConfigBuildConfig/blob/master/ConfigBuildConfig/ConfigBuildConfig.csproj

What should happen if the Debug-Staging config is selected it should read the config-staging.json and output the value in the console.

These sources suggest that this should work...


Solution

  • There seem to be two main problems here.

    1. Your Debug-Staging configuration is mapped to the Debug configuration.

    This means the condition is not being used for the EmbeddedResource.

    If you right click the solution in the Solution window, and select Options, then select Build - Configurations, Configuration Mappings you can see the mappings.

    If you select Debug-Staging in the drop down you can see it is mapped to Debug when building.

    As a quick fix here, I deleted the Debug-Staging configuration, re-added it, ensuring to check Create configurations for all solution items, then mapped Debug-Staging to Debug just for the .NET Standard CreateBuildConfig project, leaving the other projects to use Debug instead.

    After doing this I had this in the build configuration mapping:

    enter image description here

    1. The LogicalName overrides the default behaviour and becomes the full name of the embedded resource.

    Your code is assuming the resource is always embedded as:

      "ConfigBuildConfig.ClientResources.myfolder.config.json"
    

    You could change both EmbeddedResources so the LogicalName is config.json so there is no need to specify the full path.

    Alternatively, to avoid changing the code that reads the embedded resource, you could do modify the EmbeddedResource's LogicalName:

    <EmbeddedResource Include="ClientResources\myfolder\config-staging.json" Condition="'$(Configuration)' == 'Debug-Staging'">
        <LogicalName>ConfigBuildConfig.ClientResources.myfolder.config.json</LogicalName>
    </EmbeddedResource>
    

    Once those two things are fixed then data.Environment shows 'staging' when Debug-Staging is selected as the configuration, and 'production' when Debug is selected as the configuration in the main toolbar.

    To get debugging to work for the Debug-Staging configuration I had to update the configuration in the .NET Standard project. DebugType, DebugSymbols were two MSBuild properties that needed adding, but the full change is shown below:

      <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug-Staging|AnyCPU' ">
        <IntermediateOutputPath>obj\Debug-Staging</IntermediateOutputPath>
        <DebugType>portable</DebugType>
        <DebugSymbols>true</DebugSymbols>
        <Optimize>false</Optimize>
        <OutputPath>bin\Debug-Staging</OutputPath>
        <DefineConstants></DefineConstants>
        <NoWarn></NoWarn>
        <NoStdLib>false</NoStdLib>
      </PropertyGroup>