Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal NuGet Package Management In Large Solutions

Tags:

When we started our latest project (large framework), we started out with ProGet for our package server and TeamCity for build (Visual Studio Team Services is the SC). One of the solutions in the framework contains nearly 60 libraries of our code implementing everything from redis to wrappers for external APIs and common models. Each of these libraries are a nuget package. Early on in the project it was very easy to make a change in a core library, check it in, TeamCity would build and push to proget and a quick update and you were off and running.

Shortly though this became unmanageable and the team decided that while under development, no nuget packages in the common library solution would reference each other via their package but rather they would be direct references. This of course quickened the pace of development but had a nasty side effect on the consuming apps. Although the common libraries were direct references, the 7 major pieces of the microservice framework (web api, multiple mvc and some worker roles) when updating any of our internal packages would get multiple copies of the same core libraries which all of the other libs depend on.

For example, there is a single lib named "core" which has the building blocks for which almost everything is built upon in the common libraries. It has many interfaces, etc... Well since all of the other libs consume it directly, they all get a copy of core in their output directly and even more concerning is that our teamcity server handles the versioning for us so not only do they each have a copy of core but its version matches that of the nuget package consuming it.

While not great, this is still not the crux of the problem. During nuget updates in the consuming apps, each library within the app might reference a different version of core depending on the order in which the packages where updated which occasionally leads to build errors and a hunt for the rogue reference.

Now that the project is entering the final phase I want to solve this permanently but I am not sure how.

To have the nuget packages consume each other as nuget packages, a single update could take hours as one dependent package gets updated, you rebuild, it produces another nuget package which a package higher up in the chain requires, etc...

Versioning however is critical as when breaking changes are introduced we want to leverage the nuget dependencies to prevent upgrades where needed.

Has anyone else run into this and solved it? It seems like it would be fairly common if nuget is embraced fully by any development team producing a sizable project.

Update:

Example of what is happening under the hood.

CoreLib (interfaces, etc...) Lib1 (references Corelib directly, current version = v1.0.17) Lib2 (references Corelib directly, current version = v1.0.99)

Both Lib1 and Lib2 are nuget packages. An update is made to Lib1 which includes a non-breaking change to CoreLib. When Lib1 is checked in, TeamCity kicks off a build and a new nuget package is created, v1.0.18).

When Lib1's package is updated in the consuming projects, Lib1's copy of CoreLib, also v1.0.18 because AssemblyVersion is managed by TeamCity) is of a lower version than Lib2's version (v1.0.99), even though it is a version behind.

The end goal is to get all of these interdependent packages to rebuild, update and repackage themselves but how to do this automatically is really escaping me.