software solutions / project leadership / agile coaching and training

Moving past the monolith, Part 6 – Using package managers to share common code

Posted on November 4, 2017

This is part of a series of posts about Moving Past The Monolith. To start at the beginning, click here.

In my last post, I talked about creating “shared modules” that contain code that is needed across modules. Most applications will have a need to have something like this, and it can be very useful.

There are two ways to consume the shared module. You could include it in with all of your other application code, and other modules can reference it directly. In some cases, this makes sense, but now you have a problem — anytime you change something in the shared modules and it affects the consumers, all of the consumers must be updated to handle the change. If the consumers are deployed independently, you might not want to have to change that much code.

The second way to is distribute the shared module through your package manager (NuGet, rubygems, npm, etc.). The beauty of using the package managers is that package managers can store different versions of a packages, so consumers get to decide when they opt into the changes. This gives you the freedom to change shared code, but not impact consumers that don’t want to accept the changes (e.g. legacy code or things that you don’t want to retest and deploy). All of these package managers allow you to set up your own server to host packages so that you can have your own internal package source that isn’t exposed to the outside world.

This can get a little tricky when the shared module changes involve breaking database schema changes. Things like this would force all consuming modules to get updated, but you probably knew you were getting that when you decided to make the schema changes.

It’s not always that easy

While this approach might seem simple and straight-forward, it actually has some quirks to be aware of. Here are some things to watch out for.

  • Be careful of adding dependencies in your shared module that are exposed to the consumers, because you’re effectively forcing those dependencies on your consumers. A classic example is when someone adds a reference to an IoC container to the shared module, but one of the systems consuming the shared module uses a different IoC container, so things don’t work.
  • Any time your dependencies are exposed to consumers, the shared module and the consumers are forever tied to the same version of that dependency. This means that a dependency version update in the shared module will force all consumers to make the same update, and consumers will not be able to update their versions unless the shared module makes the same update.
  • There is a difference between shared modules that are explicitly created for sharing between modules in the same application and shared modules that are meant to be shared across applications. In the first case, you’re more likely to accept the version coupling that I’ve talked about, but in the latter case, you really don’t want to introduce version coupling between shared modules and many different applications (especially if they are owned by different development teams).

Read the next post in this series, Splitting up your client-side applications.

No Comments »

No comments yet.

Leave a comment

I have over 15 years of software development experience on several different platforms (.NET, Ruby, JavaScript, SQL Server, and more). I recognize that software is expensive, so I'm always trying to find ways to speed up the software development process, but at the same time remembering that high quality is essential to building software that stands the test of time.
I have experience leading and architecting large Agile software projects and coordinating all aspects of a project's lifecycle. Whether you're looking for technical expertise or someone to lead all aspects of an Agile project, I have proven experience from multiple projects in different environments that can help make your project a success.
Every team and every situation is different, and I believe that processes and tools should be applied with common sense. I've spent the last 10+ years working on projects using Agile and Lean concepts in many different environments, both in leadership roles and as a practitioner doing the work. I can help you develop a process that works best in your organization, not just apply a prescriptive process.
Have any questions? Contact me for more information.
Ditching the Office - How an everyday corporate development team turned into a remote working team
From Stir Trek 2018
From Stir Trek 2017, cbus.js 2017
Iteration Management - Your Key to Predictable Delivery
From Stir Trek 2016 and QA or the Highway 2015
From CodeMash 2016, QA or the Highway 2014, Stir Trek 2012
The Business of You: 10 Steps For Running Your Career Like a Business
From CodeMash 2015, Stir Trek 2014, CONDG 2012
From Stir Trek 2013, DogFoodCon 2013
(presented with Brandon Childers, Chris Hoover, Laurel Odronic, and Lan Bloch from IGS Energy) from Path to Agility 2012
From CodeMash 2012 and 2013
(presented with Paul Bahler and Kevin Chivington from IGS Energy)
From CodeMash 2011
An idea of how to make JavaScript testable, presented at Stir Trek 2011. The world of JavaScript frameworks has changed greatly since then, but I still agree with the concepts.
A description of how test-driven development works along with some hands-on examples.
From CodeMash 2010
From CodeMash 2010