I am working on a microservices system in c# (.Net Core) where for simplicity we place each microservice in it's own repo. Some services are very generic and some are very similar (although for different domains).
Naturally over time as the number of services grew, we identified a lot of re-usable code and patterns across those and moved those to libraries.
We moved a lot of code to nugets trying to keep it as generic as possible, with each nuget package also being it's own repo, which gave us a structure roughly like so:
Utilities
||
\/
Bindings
||
\/
Complete Kit
Where Utilities
is just a bunch of classes useful for all services; Bindings
is a nuget that contains contracts for services that do talk to others (these use a bit of shared code from Utilities
) and Complete Kit
is a one-stop solution for very common domain specific things that only about 40% of services used.
The idea was that if you write something very generic, you might grab just Utilities
and then the more specific you get, the higher level package you need.
Unfortunately, due to how nuget works (see this bug i raised: https://github.com/NuGet/Home/issues/6770#issuecomment-378466082), if i was to update just Utilities
for a project that also imports Bindings
, when Bindings
eventually gets an even higher Utilities
, updating Bindings
fails because my service imports Utilities
directly.
What this means for us now is that if i want to update something in Utilities
i need to modify code in X repositories (it's actually more than 3, but for simplicity of example i am keeping it way), where the last 2 are just updating dependency version, rebuild the stuff 3 times and wait for it to publish in my VSTS nuget feed.
As number of devs in the team grew, this became somewhat unwieldy, so we are even considering dropping all these libraries and moving to a single Complete Kit
style lib.
The nuisance of that proposal is that this one has a ton of external domain-specific third-party dependencies that have nothing to do with 60% of my other services.
Any better suggestions on how to organise this?
EDIT I understand that Nuget won't let me directly bypass dependency chain. The question is really: how do i organise the code such that i can:
- only update classes(code) i need
- allow the generic service to NOT import all the dependencies of other domain's code
- allow the domain specific code access to the same classes from (a)
Bindings
package, why is it importingUtilities
explicitly? IfBindings
depends onUtilities
, then importing the former will implicitly import the correct version of the latter too. – David Arno Sep 7 '18 at 7:12Utilities
to use in my new service. i don't really want to updateBindings
orComplete Kit
at this stage. This is the problem i am trying to solve. – zaitsman Sep 7 '18 at 7:45Utilities
, without upgradingBindings
? The fact it prevents this isn't a bug: it's a deliberate design decision to prevent you hurting yourself or your users. If that new version ofUtilities
removes a method used byBindings
for example, then the first you'd know about it would be when you get a runtime exception thrown due to the method not being found. .NET, and thus nuget, force you to recompile to detect such problems at compile time instead. – David Arno Sep 7 '18 at 8:01Bindings
andComplete Kit
whenUtilities
changes. – David Arno Sep 7 '18 at 8:01