James Legan
James Legan

Reputation: 2073

Internal NuGet Package Management In Large Solutions

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.

Upvotes: 15

Views: 1536

Answers (1)

user10008955
user10008955

Reputation:

Project references within a single solution is preferable to creating and publishing intermediate nuget packages and consuming them.

Nuget packages are an excellent way to manage versioning of "intermediate" artefacts when you have more than one solution. You can have more than one solution for a number of reason but a common reason is when you have multiple development teams.

Assuming you have an internal nuget server set up. A Visual Studio solution will not allow you to have circular references, the compiler will pick that up. Thus you need to carefully manage all your dependencies in the nuspec files for those dependencies that are not covered via a project reference within a solution.

A useful reference to the syntax of nuget package versioning is here.

Upvotes: 1

Related Questions