Have you ever worked on a project where any given developer adds nuget packages references. Have you ever audited package versions across a solution only to find your issue is version mismatches? Have you ever had two different projects depend on two different versions of the same dependency?! Have you sourced a package only to receive an error because another package relies on a different version of the same dependency? If you answered yes to any of the questions, you're in luck! Today we are going to see how Central Package Versions can help alleviate the issues of package dependency purgatory. This concept isn't new, there is now an MSBuild Sdk that provides a central way to manage the concern.
Recently I started using
directory.build.targets to provide global functionality to projects of similar types in a folder. This is something like adding roslyn analyzers to a projects in a code base, but explicitly not using it for unit test projects. It can also be a way to provide simliar package metadata to a mutli-project, multi-package solution. Instead of duplicating the metadata in each .csproj in the solution, you can provide the package details like
License to all .csproj files in the solution.
For a while this worked fine, but there was still no standard way to handle things like package version overrides, or enforcement of package versioning. It didn't matter, it was better than how things were. MSBuild Sdks provides an explicit Sdk for Centralizing Package Versions, and enforcing consistent package consumption for a repository. When I first heard about it, I was excited! As with most things, I become less excited when I find out that it doesn't work, or isn't supported for Xamarin. This was no exception. I perused the docs (scanned quickly) and was convinced it didn't work for Xamarin solutions. I was wrong.
If you use git, then drop a
packages.props file in the root directory of your repository. This
packages.props file is going to be the single source of truth. That means you can no longer right click and add a nuget package to a single project, it has to be added here. The packages props will maintain a global version reference.
I prefer to put a common props and target file at the root of the repository. You don't have to, you can add the following to a directory target, or on each individual .csproj file. Regardless of where you place it, the following xml will tell the MSBuild engine to use the Central Package Version Sdk.
<Project> <Sdk Name="Microsoft.Build.CentralPackageVersions" Version="2.0.52" /> </Project>
packages.props you can now define a few specific reference types.
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" />
<PackageReference Include="System.Reactive" Version="4.*" />
<PackageReference Update="ReactiveUI" Version="11.*" />
At this point, it would have registered that I said, no right click and adding nugets. Yes, I know some readers will find this too complicated. The tedious nature of having to update XML is just too much for some to bother with. Remember one of the benefits of this Sdk is to make maintaining a solution easier. So there is a trade off. You trade a simple GUI user experience, for not having to dig through every single project just to find a single project has the wrong dependency version.
I won't bore you with showing you how to setup the
packages.props instead here is a link to a Xamarin.Forms project using it, Happy Package Management!