I previously blogged about the main themes of the Helix principles, and how each of the main aspects of Habitat achieves the aims of Helix. Of course, Habitat is only one interpretation of Helix - but unfortunately it looks like copying Habitat has become a common way of implementing a Helix solution. Habitat is a coherent implementation of the Helix principles, but it is meant only as an example. In this post I take a look at way of changing one of the “dominant” aspects of Habitat to arrive at a different implementation approach.
How many Visual Studio projects?
The aim of this blog post is to (at a very high level) work from Uncle Bob's "Principles of package and component design" (the main inspiration for the Helix principles) to a condensed description of Helix, and then to take a look at how the main features of Habitat fulfil the Helix aspirations. Why do I think this is needed? In my opinion, the official documentation in its current state entangles Helix with Habitat in many places (although if you bear this in mind when reading it, it is still a great guide and worth reading) making it hard for newcomers to think about Helix without having to refer to Habitat example implementation.
Helix also encompasses a lot of "best practice" stuff, a lot of which I’m disregarding below, as you should already know and follow most of these practises without knowing them as "Helix"
Quick and simple post - as the title suggests, this is how to deploy Habitat on top of a newly installed Sitecore developer instance (both version 9.1). You should use the general Habitat setup wiki if you want to install Sitecore 9.1 and Habitat at the same time. Why might you want to install a Sitecore vanilla instance first? Perhaps you want to take a look at vanilla Sitecore before looking at Habitat, or perhaps you are curious as to which vanilla files Habitat amend and adds to. By the way, to get Sitecore 9.1 installed locally take a look at my previous blog post.
I'm interested in the productivity and quality of development teams, and the output of development teams cannot be analysed in isolation - the team's work must be providing value to the business it serves. Communication mismatch between tech and non-tech folk is something I've written about previously.
As "automation" has been a buzzword for quite some time in the enterprise software world - and in most cases for very good reason - I thought it would make a good practical example of situations where tech teams lose sight of the most meaningful objectives.
If you've implemented Web API controllers in Sitecore 8.1 (and therefore MVC 5.2) you may have noticed that requests to these controllers create and/or maintain an associated ASP.NET session on your server. But there may be situations where session isn't required for this controller (such as a very "stateless" REST API endpoint), so how can you remove session and save your server a bit of work?
Sitecore Support helped me find the answer to this; If you dig down from the Sitecore.Mvc.Pipelines.Loader.InitializeRoutes pipeline processor, you'll see all route handlers getting wrapped by Sitecore.Mvc.Routing.RouteHttpHandler, which eventually ensures that session is spun up when that route is used.
However, if you register your API routes in a pipeline processor which runs *after* Sitecore.Mvc.Pipelines.Loader.InitializeRoutes, this doesn't happen. See a bit more detail on registering custom MVC routes in Sitecore here.
If you're familiar with .NET MVC, you'll know how MVC routing can be used to consume the structure and elements of a URL path and parameters to resolve to a particular Controller class and Action method. This also takes care with ensuring that the requisite parameters are extracted from the URL and passed to the Controller.
If you're familiar with Sitecore MVC, you'll know that each rendering on a Sitecore page/item resolves to its own Controller, enabling dynamic composition of page output from multiple Controller classes. Routing-wise, Sitecore MVC works very much like Web Forms versions of Sitecore - i.e. the structure and elements of the URL path are mapped pretty much directly onto the Sitecore item tree in order to resolve the "context" item.
A key part of Sitecore's personalisation offering is the ability to gear content towards a user's location. Sitecore provide plentiful information to help you set up your application to retrieve geo data for each originating IP address. Once you have this set up, Sitecore will call a web service behind the scenes, whenever it encounters a request for an IP address which it hasn't seen before. The result of this call is cached in a MongoDB collection to ensure that each IP address is only ever requested from the web service once. Once this process has completed, the Tracker.Current.Interaction.GeoData object is populated with the relevant geo data, and the out-of-the-box location-based personalisation rules will be ready to fire.
I've recently pushed to GitHub some wrappers and interfaces for many of the common Sitecore API classes, which I put to good use on a recent project - this will hopefully save other people doing the same work! They can be found at https://github.com/RedMoonLimited/SitecoreWrappers - you'll also need to reference the Sitecore.Kernel and Sitecore.ContentSearch dlls; note that this code was written against Sitecore version 7.1 rev 140130. I've also included a few fairly hastily written "builder" classes (which may come in useful when creating common 'aggregates' of mock Sitecore objects for testing purposes) plus some example code and its unit test to get you started.
Recently I was configuring a Sitecore 8 solution (rev. 150621) to use Solr as its indexing provider, instead of Lucene. I'd also set up the solution to use the Sitecore Media Framework Ooyala Edition module (FYI, Ooyala is an online video services provider - the module enables content editors to 'import' videos, and then embed them into their pages using, for instance, the Rich Text Editor or the provided MVC controller) - the version we are using is 2.1 rev. 150323. The module comes with its own index - and a Lucene one at that (defined in the supplied file Sitecore.ContentSearch.MediaFramework.Ooyala.config) - which I had to disable as part of the Solr setup work.
I came across an interesting set of challenges recently when working on a Sitecore 7.1 project (version 140130 to be precise) and using the ContentSearch indexing API.