Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent content files to be removed during incremental build?

I have a Visual Studio 2015 Update 3 solution with 3 projects:

My top-level application is MyApp which has a project reference on ClassLibrary2 which in turn has a project reference on ClassLibrary1:

MyApp -> ClassLibrary2 -> ClassLibrary1

The ClassLibrary1 has a data file, data.bin, that is required for its normal execution. It is expected that this data file will be found in a Resources/ sub-folder relative to where the ClassLibrary1 assembly is when the application is executed. The structure of the ClassLibrary1 is similar to:

ClassLibrary1.csproj
    Resources/
        data.bin
    MyClassBehaviorDrivenByData.cs
    ...

The data.bin file has its Build Action property set to Content (I have also tried with None) and its Copy to Output Directory set to Copy If Newer.

If I do a full solution Rebuild, the data.bin file finds its way to the output directory of MyApp, as expected. However, if I do some changes in the MyApp project and build the solution, the data.bin file is deleted from the output directory of MyApp (note: the Output window shows that only MyApp is built since only the code of MyApp was changed).

Workarounds:

  1. I could use post-build steps in MyApp to forcefully copy the data file to the output directory each time MyApp builds. However, this goes against the principle that the developer "owning" ClassLibrary1 should not have to worry about modifying post-build scripts in consuming projects if he adds a new data file, modify existing ones or move them elsewhere.

  2. I could directly add a reference to ClassLibrary1 from MyApp. However, this violates the desire to hide away the ClassLibrary1 functionality/API under the ClassLibrary2 API (i.e., I don't want ClassLibrary1 API to leak into MyApp).

My questions are: what causes the data.bin file to be deleted from MyApp's output directory during incremental builds of MyApp and is there a way to prevent this to happen without using one of the 2 workarounds listed above?

like image 900
Fredpo Avatar asked Oct 29 '22 20:10

Fredpo


1 Answers

The reason is that that file is deleted in Incremental Clean task, that is used to make sure the files are newest (but it just delete files for your scenario). To deal with this issue, you can add a new target to copy necessary files to the target folder.

For example(edit csproj file, add this code to the end (before ):

 <ItemGroup>
    <resourceFiles Include="..\ClassLibrary1\Resources\*.*"/>
  </ItemGroup>
<Target Name="AfterBuild" DependsOnTargets="CopyFiles">
 </Target>
 <Target Name="CopyFiles" Inputs="@(resourceFiles)"
        Outputs="@(resourceFiles->'bin\$(Configuration)\Resources\%(filename)%(extension)')">
    <Message Text="after Copy files" Importance="high"/>
    <Copy
           SourceFiles="@(resourceFiles)"
           DestinationFolder="bin\$(Configuration)\Resources"
        />
  </Target>
like image 63
starian chen-MSFT Avatar answered Nov 15 '22 04:11

starian chen-MSFT