Sitecore released a new demo site late September called Sitecore Habitat.
There is nothing new in Sitecore supplying a demo site but this one is nothing less than groundbreaking, it is a real revolution in the way that Sitecore teaches developers to work with their product.
In the latter days Sitecore would never explain how to structure your solution. They would merely supply limited demos showing how different functionality can be achieved using the Sitecore API. Nothing about how to structure a large solution that has to be easy to maintain over time.
This has now changed. Sitecore Habitat introduces an architectural approach called Modular Architecture.
The origin of Modular Architecture
Modular Architecture is primarily derived from the work of Uncle Bob (Robert C. Martin). It is an architectural approach that was formalized for Sitecore solutions at Pentia where it has been in use since around 2009.
The current version of the architecture, that contain the concept of layers, is used in all solutions made by Pentia since 2012 where we referred to the architecture as Component Architecture.
The principles in what we called component architecture and what now is called Modular Architecture are the same. For a reference on component architecture see my slides from SUGCON 2015 on component architecture
Is Modular == Component?
Yes, in this case, it is just a case of naming but I bet there is a good reason for this.
The name component architecture would often confuse developers who was not acquainted with the architecture. The word component was understood as a single presentation, rendering in Sitecore terms, and not as a full feature of the solution which was what the name actually intended.
This lead to unfortunate misunderstandings and an unnecessary extra effort had to be put into explaining the meaning of the word component before we could get down to speaking about the important stuff.
Uncle Bob refer to the architectural principles as “Principles of Package and Component Design” in his book Agile Principles. Patterns and Practices in C# where he writes
The term package has been overloaded with many meanings in software. For our purposes, we focus on one particular kind of package, often called a component. A component is an independently deployable binary unit. In .NET, components are often called assemblies and are carried within DLLs
Agile Principles, Patterns and Practices, Robert C. Martin, chapter 28 – Packages and components
Nowadays the word component has been overloaded with many meanings in web development so dragging it a level up and calling it Modular Architecture?
Yeah, that makes sense, I can live with that name even though it will take some time to get used to not calling it component architecture 🙂
A component, or now rather a module in Modular Architecture, is a feature in the solution and not just a single assembly or VS Project. A module typically consist of template and rendering items, configuration, tests and so forth along with the assembly. With this in mind then the name Modular Architecture makes a lot of sense.
The name, although important, is still secondary to the understanding of the principles behind it.
Why follow Modular Architecture?
Basically to have more time to work on fun stuff. That is at least my favorite argument. The experience at Pentia has shown that the complexity of support issues goes down significantly so the time spent on support is at an absolute minimum. And I for one rarely enjoy working on support issues, I want to work on new stuff and I have more time for that now. The general quality and maintainability of our solutions ensures that we only work on support cases at Fridays on most of our solutions and Fridays are even only half a working day due to meetings and our play time. Some Fridays there aren’t even enough support cases to go around for everyone so we get to work on projects.
Basically we have managed to keep maintenance costs down to a minimum on our own solutions even though maintenance costs still does grow some over time.
The minute you start developing a solution the clock starts ticking and you know that some day in the future the solution will have to die, that is just a fact of life. It starts to build up technical debts from day one due to different decisions taking during development to meet the requirements. The more time pressure, the more likely developers are to take bad decisions that adds technical debt. So on a solution where things go pear-shaped this can end in a vicious cycle where more and more technical debt adds more and more pressure which in turn adds more debt.
One day it will even be more expensive to maintain the solution and add new features than it will be to replace it completely with a new one.
In the worst cases I have seen this point was reached even before the solution was delivered to the customer. I guess you could call it stillborn solutions where development was deadlocked due to poor or completely lacking architecture and sometimes also incompetent implementation partners.
I have unfortunately witnessed quite a few of these solutions in my role as a professional service consultant at Pentia. It is a real shame since these solutions brings down the reputation and good name of Sitecore and has huge unnecessary costs for everyone involved.
For us developers such solutions are living nightmares that probably has brought many good people down with stress, caused divorces, broken families, addictions and probably also deaths.
Luckily most solutions are not stillborn. They live for quite some time but
Due to changes in both technology and business requirements, all code will decay over time
The goal of modular architecture or any good solution architecture is basically to keep the maintenance costs down over time even though the costs will increase slightly no matter what, that is just a fact.
Modular Architecture ensures this goal by following some simple principles that preaches low coupling between modules in your code base. Basically a healthy dependency flow. The low coupling ensures that decayed code easily can be replaced without impacting the whole code base. More on these principles in later posts.
The methodology that the architecture also preaches ensures consistency and easy maintainability. At Pentia we do not have dedicated supporters for specific solutions, no lone heroes, everyone can potentially work on any of the in-house solutions each and every support Friday. This flexibility has huge advantages for both us and our customers.
In some of our original training material we ended out with a food analogy. Credits to Thomas Eldblom and/or Jens Mikkelsen.
If Sitecore was a dish consisting of the following ingredients:
Where the rice are items, the shrimps are templates, the salmon are renderings, and the broccoli configuration and so on.
Then you could prepare a nice paella for your customer
But what if the customer turned out to be allergic to mussels? Then the whole dish would be ruined. Any attempt of throwing out the mussels would still leave traces of taste and deteriorate the whole dish significantly.
By following the principles of Modular Architecture you can instead end up with a nice, healthy and tasty set of sushi
I had to update the training material once and stumbled upon this image that I just had to add to the analogy.
If a bug is found in one of the Sitecore Sushi pieces, then you can simply throw out that single piece. It will not change or deteriorate your salmon maki rolls or any of the other sushi. You can also leave it on the plate for some time whilst you eat the rest.
Being able to discard features in this manner is extremely beneficial and I as an architect on large Sitecore solutions cannot live without this option now when I know how easy it is to obtain. You just have to follow these simple principles introduced in Modular Architecture.
When a new developer joins my team I can in full confidence instruct him, or her haven’t happened yet, to work on a feature of the solution with no concerns. I know that the rest of the solution is safe and rookie code will not break it or bring down the overall quality. Everyone has to start somewhere and by following the principles of Modular Architecture it is even easier to get new developers familiar with Sitecore quickly.
To be honest then I myself can also have a good time writing quick and dirty code just to get the job done in a pragmatic way. It can be necessary sometimes especially when some print-designers have gone rogue and tried to draw up a website.
I can write this dubious code that does the job with full tranquility as long as it is well confined within an easily detachable module that is isolated and can be replaced without impacting the rest of the solution.
All code does not have to win beauty contests. As long as nothing else depends on it and it is not part of the foundation of the solution then quick and pragmatic code will do the job better in the long run.
Simplicity is key, not complexity. Problems can be complicated, solutions cannot.
There are many more reasons for following modular architecture depending on your role and your view on the world. I have yet to meet someone working on a Sitecore project on either side of the table that does not benefit in some way from Modular Architecture.
I am excited about Sitecore now does an effort in teaching these principles to the Sitecore community and I will encourage all Sitecore developers to show their support and learn these principles and techniques.
This will help us all and hopefully in the long run free us from spaghetti monster solutions that get thrown around various partners and degrades Sitecores reputation.
How do I get started on Modular Architecture?
Start out with watching these 3 videos by Thomas Eldblom from Sitecore
Then when you are done with these get the Habitat code from gitHub and follow the Sitecore Habitat installation instructions.
That’s it, then you will be ready to explore the architectural principles and apply them to your solutions. Getting the hang of identifying modules and creating the right structure takes some experience though.
I would highly recommend you to read chapter 28 in Agile Principles, Patterns, and Practices in C# (plus the rest of the book) and Clean Code: A Handbook of Agile Software Craftsmanship both by Robert C. Martin aka Uncle Bob.
Another important reference is his slides on Advanced Principles of Component Design.
What about the Habitat code base itself?
The Habitat solution itself and the technology stack it depends on is state of the art at the moment. The solution relies on all the cool new stuff here-among the new Task Runner in Visual Studio 2015. I simply love that Gulp and Grunt has become first class citizens in Visual Studio. It is about time that we get a de-facto standard for task runners in .NET. Unicorn is used for serialization and thumbs up for that as well, I love Unicorn 3, it is simply ingenious.
Code will decay over time and as I wrote Habitat is based on what is state of the art today, what will be state of the art tomorrow no one knows. The technology stack behind Sitecore is also rather regularly updated so I will highly encourage Sitecore to release a new Habitat for all new Sitecore versions. If the Habitat is to be more than just a firefly then it needs to be fully supported and updated by both Sitecore and the community also tomorrow and the day after. Otherwise the Habitat solution itself will decay and built up technical debt until it will be more of a burden than a helping hand. Habitat should always work as a clean slate demo / reference for that specific Sitecore version. The architectural principles are fixed though and does not change but the way they are brought into live will also change slightly with time and technology.
Whats next?
My next two posts will be about the layering concept in Modular Architecture, the thoughts behind them and also how the layering concept can be extended in different fashions to support large-scale solutions with several subsites and brands.
Are you interested in Modular Architecture training sessions?
Then you are always welcome to contact me. Pentia offers specialized training courses for Sitecore developers on request.
Anders Laub Christoffersen
Anders has been working with Sitecore for over a decade and has in this time been the lead developer and architect on several large scale enterprise solutions all around the world. Anders was appointed the title of Sitecore Technical MVP in 2014 and has been re-appointed the title every year since then.
- Web |
- More Posts
This demo / framework will be a huge help going forward. A great source of ideas, and it can probably be made even better through collaboration.
One thing I noticed after first loading the solution, is that a lot of the external components exist in multiple versions. This can be confirmed by looking at the “packages” folder after a NuGet Restore. AutoFixture, Sitecore.FakeDb and others are found in 2-3 different versions. Not necessarily a major issue (and in fact could be considered an intrinsic part of having independent modules), but personally, I like to keep one version of a NuGet package per solution. (And I wish there were a simple built-in way to do this.)
Another example, there is only the 6.0.8 version of Newtonsoft.Json installed, but the various web.config/app.config files redirect to 7.0.0.0 or 6.0.0.0. Reminds me of this article: http://jeremydmiller.com/2014/04/28/fubumvc-lessons-learned-strong-naming-woes-and-workarounds/
Hi, thanks for the comment. Yes, I wish there was a built-in way of having one global solution packages.config too for the common packages.
At Pentia we have been struggling a bit with finding the best approach for NuGet in Modular Architecture the last 2 years. The best approach we came up with so far is to have a packages.config per VS project as in Habitat.
Then we use some custom project templates, one for MVC projects, one for WebApi and one for framework components. In these templates we ensure that packages.config reference the same version of the common NuGet packages, for example MVC and NewtonSoft.
The custom project templates are easy to make and distribute so it is not that big a deal at all.
It is a bit of a hassle when the versions then need to be updated during a Sitecore upgrade though. Then you need to update all existing packages.config files along with the project templates. I really miss a * functionality in NuGet like npm offers.
We also tried to have a single packages.config on the project layer in the Website project. This worked fine for Visual Studio 2013 and WebForm but in VS 2015 the built-in MVC project templates adds NuGet packages to each and every project along with a EnsureNugetPackageBuildImports element in the .csproj file which makes build fail if the packages are missing.
This made us make our own project template so we didnt have to remove the references each time we made a new module. A blog post on this will be written soon either by me or one of my colleagues.
One might also argue that having a single packages.config on the project layer makes a weak dependency from the Domain layer feature module to the packages.config on the project layer. So a single file actually breaks the architectural dependency flow.
I would love to hear other ideas on how to tackle NuGet packages.
–Anders
VS2015 update 1’s new NuGet packages for solution dialog has a ‘Consolidate’ tab that is for just this use case: to normalize versions of a package.
Nice, I’ve noticed it recently but haven’t tried it out yet.
Hi Anders!
Great hear about this topic.
In case we don’t want to re-use compontents in other projects, what is the benefit of having a separate Visual Studio project and DLL for reach component?
Compared to the approach to create a separate directory and namespace for each component and being disciplined about not introducing undesirable references between these namespaces.
You can also have certain rules between namespace dependencies, which would break your build. It’s simple to setup such NDepend rules, see these articles:
http://www.codinginstinct.com/2008/08/less-assemblies-more-namespaces.html
http://www.infoq.com/articles/NDepend
I sense that working with many project files can cause some difficulties.
E.g.
– Managing and updating NuGet package versions across many projects. We use many NuGet packages.
– When switching between git branches Visual Studio likes to freeze if it has to reload too many project files.
To me it seems to add complexity which is not a necessity to keep the architecture clean and is in certain cases over-engineering the setup.
Separating per namespace seems to be a reasonable alternative and I consider this decision rather a matter of taste and not a rule of thumb.
Thanks,
Tamas
Hi Tamas,
Re-usability is just a positive side-effect and not a goal in itself in Modular Architecture. So typically no modules is re-used 1-1 between solutions even though they often can be very similar there is almost always some domain specific differences. A genius framework component that evolved in a solution is typically re-used when it has matured, for example SitecoreExtensions, this is then precompiled and put on NuGet. A blog post will follow on this topic 🙂
There are many benefits of having an actual VS project and assembly for each and every module and I would advice against only having one project per layer or similar and then use folders and namespaces.
Discipline is by experience not enough, not everyone possess it, someone will break it, you need the insurance of strict layering which independent VS projects provides. Yes, you can use a tool like NDepend to ensure some layering between namespaces but this only works for references made in code, not configuration etc. etc. It will be too easy to make weak references.
The Git issue you mention is not something that I experience. This is probably a question about tooling. I prefer to use git bash from CMDer (http://cmder.net/) good old command line style.
As the other comment on this post describes then NuGet has shown some challenges. I see this as a challenge with NuGet and not the architecture.
It is important never to let your tools be the decisive factor in choosing architecture and methodology. Tools are to assist you not decide for you.
In my opinion it lowers complexity significantly to have a project per module. The overview becomes much clearer, dependencies much clearer. It is rather the opposite of over-engineering, it is the essence of simplicity.
Putting everything in the same “basket” and keeping track of your own actions using third party tools and discipline, that is adding unnecessary complexity 🙂
–Anders