Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Nesting Files in a Project

5.00/5 (2 votes)
5 May 2017CPOL1 min read 8K  
Nesting files in a project

As part of the code generation work, I wanted to group the generated code file with the associated source. This was provided for free under project.json if you kept the filename the same and simply appended a new extension, however, this has been lost in the conversion to MSBuild files.

Solution Explorer

Having said that, the project file format for .NET core projects in Visual Studio 2017 has been greatly simplified, for example, you no longer have an entry for each file in the project. There also exists a nice Microsoft.Build NuGet package that simplifies working with the project file and, as a bonus, it also works for .NET Core applications.

Implementation

The way to get Visual Studio to group an item is by adding a Compile item with the DependentUpon set to the parent item, i.e.:

XML
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    ...
  </PropertyGroup>

  <ItemGroup>
    <Compile Update="Child.cs">
      <AutoGen>True</AutoGen>
      <DependentUpon>Parent.txt</DependentUpon>
    </Compile>
  </ItemGroup>
</Project>

This can be done in code quite easily by the following code:

JavaScript
string project = "Example.csproj";
string childName = "Example.txt.cs";
string parentName = "Example.txt";

// Load the project file
var root = ProjectRootElement.Open(
    project,
    ProjectCollection.GlobalProjectCollection,
    preserveFormatting: true);

// We need to put the Compile in an ItemGroup
ProjectItemGroupElement group = root.AddItemGroup();

// MUST set the Update attribute before adding it to the group
ProjectItemElement compile = root.CreateItemElement("Compile");
compile.Update = childName;
group.AppendChild(compile);

// MUST be in the group before we can add metadata
compile.AddMetadata("AutoGen", "True");
compile.AddMetadata("DependentUpon", parentName);

// Save changes
root.Save();

As you can see, the code follows the XML structure and can be easily expanded to re-use the same ItemGroup for all the dependent items. Also worth noting is that I'm preserving the formatting of the project file by specifying true for the preserveFormatting parameter in the call to the Open method, as the project files can now be edited manually from within Visual Studio. It would annoy me if another tool had overwritten my hand-crafted changes. 🙂

Filed under: CodeProject

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)