NuGet CPM when using Git submodules
I've written about NuGet Central Package Management in the past, but since then there were some news in this field. Most importantly, the .NET Upgrade Assistant Visual Studio extension and command line tool has been extended with support for upgrading projects to Centralized Package Management.
This encouraged me to try introducing Central Package Management to a couple of applications I didn't dare tackling before. They are special because they rely on Git submodules for sharing the common class libraries:
- The common class libraries are in their own Git repository.
- This class library repository is included as a Git submodule in the application repository that depends on them.
- The application projects have the class libraries from the Git submodule included as project references.
This makes it impossible to have a single Directory.Packages.Props
file with NuGet package versions for both application and class library projects in the application repository root as that would mean that the projects from the submodule would have the versions of their dependencies defined outside their Git repository. Instead, they need their own Directory.Projects.Props
file in the root of their repository. And the Directory.Projects.Props
file from the application repository root folder doesn't apply to them. A simplified desired structure is as follows
- Application root (Application Git repository)
Submodules
folder- Class library repository root
Directory.Projects.Props
file for projects from the class library repository- Folders with class library projects
- Class library repository root
Directory.Projects.Props
file for projects from the application repository- Folders with application projects (some of them referencing class library projects)
The .NET Upgrade Assistant is flexible enough to introduce the NuGet Central Package Management as I described it above. The process is rather simple, but it has to be done in two steps.
First, the projects in the class library repository need to be updated. With the .NET Upgrade Assistant Visual Studio extension installed, open the solution from the said repository containing all its projects. Right click on any project in the Solution Explorer (not the solution itself) and click on Upgrade in the context menu. Select the NuGet central package management (CPM) upgrade option and keep all the projects checked in the tree view on the next page:
Click Next, change any settings on the last page if needed and finally click Upgrade. Wait for the upgrade to complete, and close the solution. This will create a Directory.Projects.Props
file in the root of the class library repository.
Next, open the solution from the application repository with all application and class library projects included. Follow the same steps as for the class library project until you reach the project selection tree view. Make you sure you uncheck all projects from the class library repository, but keep the projects from the application repository checked:
Navigate to the end of the wizard and wait for the upgrade to complete. This one will create Directory.Projects.Props
file in the root of your application repository.
Updating a package in the solution after it's set up like this will work exactly as you would expect it to: if the package is present in both Directory.Projects.Props
file, they will both be modified:
In a way, you get semi-central package management:
- You don't need to specify the package version in each project anymore because the version information is moved out into separate files.
- But you also can't modify it in a single file because you need to commit the changes to two different repositories.
Central package management significantly simplifies consolidation of NuGet package versions in large solutions with many projects. It works really well even you want to specify versions in multiple files, each for its own set of projects. And the .NET Upgrade Assistant can set up those files correctly without any manual modifications.