Sitecore Architecture Best Practices – Part 1: Understanding Architectural Basics
When I first started to get to know Sitecore, after learning the user interface my main question was “But how do you develop for Sitecore? Where do you create the Visual Studio solution and what are the recommended practices around that?” Years and years later after going through trial and error and many Sitecore implementations I have polished off a few solution architectures for Sitecore development that have become the base for any Sitecore development. Whether you are new to Sitecore and are trying to figure it out just like I was years ago, or you are a seasoned developer and are curious about Sitecore best practices, with years of experience, you will find these series of articles interesting. So, read on!
Sitecore Content Management System as a Stand-alone Application
Before we dive into different solution design patterns for Sitecore, let’s first do our due diligence and lay down the foundational knowledge of Sitecore, as a stand-alone application.
Sitecore is at its essence is a .NET application. From just a first glance, we can recognize familiar to us folders and files in the root directory: App_Config, App_Data, bin, web.config, global.asax….etc. In the Sitecore web.config (most likely the biggest web.config you have ever seen) you will find a large section of <pipelines /> which contains a series of commands and steps that get executed for certain events. As a new Sitecore developer, it may be a bit overwhelming to try to understand all that is happening under the hood, so for now just understand that once the CMS has initialized (let’s assume it is a fresh Sitecore install), all requests to the assigned domain populate a large Sitecore.Context object that is accessible through the Sitecore.Kernel.dll, the library that provides access to the majority of Sitecore’s basic API calls.
Knowing this we can say that if we are creating a solution for Sitecore and want to access some data hosted by the CMS and perform some of the most common tasks, we should create our project with a reference to Sitecore.Kernel.dll.
Now, Sitecore solutions are not stand-alone applications, they are rather modular, or component-based add-ons to the already existing application. Think of creating a website to run on Sitecore is like writing a plugin that makes use of the Sitecore API and generates a web page. So, no hitting F5 in Visual Studio!
Finally, in order to make our code run under the Sitecore context, in its basic form, only two steps need to be performed:
Step One: the compiled project dll library containing the backend logic must be placed into \Website\bin (http://www.sitecore.net/Learn/Blogs/Technical-Blogs/John-West-Sitecore-Blog/Posts/2010/11/The-Sitecore-Context.aspx) .
Step Two: requests to particular URLs must be bound to our code. This is usually done through the presentation layer, where Layouts are defined along with Sublayouts and Renderings, or through a manual endpoint registration, which is something you would do for web service calls.
That’s it! These are the basic requirements for running you custom code on Sitecore; everything else is optional and use case –specific. Make sure you really understand this, as it will help us answer some of the most common questions I have run into about designing a Sitecore architecture.
Sitecore Architectural Myths and Misconceptions
Before we dive into the world of confusion, let’s give a Lehman’s definition to a solution architecture. In simple terms architecting is organizing, and design patterns could be treated as our daily habits. I personally like to use an analogy of moving into a new apartment to architecting a solution (yes I have moved a lot 🙂 ). After all the discovery that has been done we usually end up with a lot artifacts: UX documents, designs, object models, conceptual diagrams, use case diagrams, database schemas… etc. I associate it with all the stuff I brought with me to a new apartment from the old place – it’s messy, disorganized, and overwhelming. Imagine standing in a new empty apartment, full of boxes and stuff everywhere, thinking “How am I going to make this work? How am I going to place all the furniture and put away all this stuff so it all fits, becomes easy to find, easy to change or move around, so it looks good, -easy to use, easy to clean, and of course takes less time to do it all in. Sound familiar? As architects, we are trying solve the same problems with every new application. There are things that are required by the layout of the room (solution framework), and some require some improvisation (connecting several models in a single view). In the end after it’s all said and done, we are hoping to end up as close to our original vision of the architecture as possible. The reason why I say “as close as possible” is because there are always things like scope creeps and leaky abstractions that find a way to sneak into your application and ruin your day.
This same analogy I like to apply to Sitecore solutions, think of the CMS as a building, and websites as rooms. Every room can be organized differently the way the people living there prefer, but they are still a part of the same building, and get their utilities from the same companies.
So, as you read through the questions below, keep a firm grip on the two essentials mentioned above, and the apartment analogy.
Do you have to create a separate project for each website hosted in the same Sitecore instance?
No. This is similar to asking can we just make the entire building one big room? – Sure, good luck getting some privacy, but sure!
Although it is a preferred approach to create multiple projects for separate websites and even multiple projects for the same website, as we will find out later, at the end of the day as long as we place the generated DLLs into \Website\bin and register routes – it will work just fine.
Do all projects that are running on the same Sitecore instance have to be a part of the same solution?
No. Just like you can have sections in building, there could be multiple solutions living in a Sitecore environment.
There is no technical limitation to this, just like with any .NET application. Solution files only help us easily open our code in Visual Studio and setup some basic configurations. In one of my previous projects with multiple shared Visual Studio projects we had three solutions for two websites – one for each website and one for the shared code. The shared code solution file only opened the shared projects, and the website-specific ones opened the code for that website and the shared code.
Do websites running on the same Sitecore instance have to use the same architecture or design pattern?
No. Otherwise, it is like saying, just because I like to put my keys on a bar stand when I get home and my next-door neighbor puts them on a shelf somewhere – our rooms cannot exist in the same building.
The project and solution structure is at a higher logical level from the code itself. The solution architecture helps us create solutions that are simple to understand, learn and maintain. Essentially, all of our project backend code files (*.cs) no matter the project folder structure, get compiled into a library, and as long as we copy that library into \Website\bin, register routes that don’t conflict with each other, it will work just fine!
In fact, not only can you host projects with different architectures, you could combine the WebForms and MVC frameworks in the same solution, website, and this might blow your mind – the same page! (this is not a trick, yes, you can build a web page using Sublayouts and MVC renderings using the Sitecore presentation layer with just a few tweaks).
Do I have to put my solution file into the root of the Website folder?
No, you don’t have to move into the first apartment you see during your first visit.
Although this may be a good learning exercise to understand how to create custom code for Sitecore, your solution could live anywhere: Website folder, a custom subfolder under Website, outside of the Website folder, or even on a different computer! What matters is that the compiled library and the routes get copied and registered.
Don’t let Architecture Astronauts suck you into believing otherwise. Always keep it simple and remember that to get our code to run in Sitecore, we need to copy our compiled library into the \Website\bin that references Sitecore.Kernel.dll and register the routes.
Sitecore Solution Architecture Goals
Now that we have uncovered some of the myths and misconceptions, let us now look at what a good Sitecore architecture should be, which is the most important part, right?! This is a list that, in my opinion, each Sitecore hosted solution should satisfy at a bare minimum.
There are tons of material written on solution achitectures and best practices; one of my personal favorites is the MSDN eBook Patterns & Practices: App Architecture Guide 2.0. Since there is already more than enough information written about preferred practices, I will only focus on the key aspects that I feel are especially important when building websites in Sitecore.
Beware of Becoming an Architect Astronaut
Of course, before jumping into the list, I feel like a word of caution is needed here – if you are reading this article, then there is a good chance that you are like me – continuously learning and forever curious about better and more efficient solutions. In addition you are also likely to take pride in what you do, constantly striving to do a better job, and follow industry standards…follow every development best practice, test every piece of code, comment every method, follow every design pattern, come with unthinkable gymnastics to follow strict MVC or MVVM patterns…etc. If you didn’t yet get the point – what I was describing is a perfect path to becoming an Architect Astronaut. Joel has described the Architect Astronaut perfectly. Although it is very easy to speak about this kind from a third person, sometimes this syndrome sneaks up on the best of us and the next thing you know is you – spending hours on figuring out how to fix a leaked abstraction, because, getting it to work means proving that the design was in fact good and the solution – bulletproof, which is a lot to an architect full of pride, right? When you find yourself focusing on prioritizing standards over the goals below – you are in trouble!
Code is a Liability
As you read through the following goals of the architecture keep in mind that a goal of any good architecture is provide the best solution with the least amount of code. Code is a liability, therefore the less of it we write – the better! Whoa! Isn’t that a “catch 22”? Wait a minute, are we saying that the less code we write – the better developers we are? – Yes, in a way. The less code we write to accomplish any particular goal – the better developers and architects we are. The important thing is to not lose track of the goal. In other words, the best solution lies somewhere between hours spent on a small unnecessary detail to taking a lazy shortcut (although, data template icons are important, I could probably take a long vacation to some islands in the total time I spent on choosing “just the right one”!).
Goals of a Sitecore Architecture
So here we are the list of Sitecore Solution Goals –
- Simplicity – one of my idols of childhood, Bruce Lee once said, “It is not a daily increase, but a daily decrease. Hack away at the inessentials.” Every intelligent person can make things complicated, and this cannot be more true for Solution Architects, but it takes a genius to keep it simple. Remember this – as an architect, your primary job is to make developers’ life easy!
- Re-usability – the original idea of developing a Content Management System was to give control over content to Content Editors, but how about going a step further – giving control over components, widgets…etc.? What if your editors want to use the body of one template, and the side-rail widget from another three, can they do that easily without a developer’s involvement? Only solutions that prioritize re-usability of components, can make this happen.
- Scalability – Sitecore solutions tend to grow into healthy-sized websites, more often than not hosting multiple websites! So even though the first website you are building for Sitecore might seem small, make sure to set the base for future growth just enough without going overboard and blowing up the scope!
- Extensibility – this one goes along with scalability, as you never know when you would need to add more features, websites, services..etc. CMSs grow quicker than stand-alone applications and with growth comes a lot of need for extending previously built functionality
- Flexibility – CMS solutions are usually more dynamic in their nature than stand-alone applications in the sense that they tend to change more frequently. Marketers continue to drive this ship, and those guys have a magic hat with endless ideas. Make your code flexible, robust, and ready to be updated very easily, if needed
- SOLID – an age-long set of principles, that is well described on CodeProject in an Object Oriented Design Principles article.
That’s it! As long as we keep focused on these six principles and keep our head on our shoulders, we should be on the right track to properly organizing our Sitecore “rooms”! In the next part of the Sitecore Solution Architecture Series we will take a look at each of the goals in more detail.
Please let me know your thoughts on this in the comments below. Cheers!