Sitecore Configuration Layer Config - Layers.config

In Sitecore v9, Sitecore divides configuration files into layers, which in its simplicity gives you the ability to control in which order, the config files are loaded. This is handled in a new config file named Layers.config. The Layers.config file is located at the website/App_config/Layers.config and contains four layers for areas in Sitecore to manage. The layers are:

  • Custom
  • Environment
  • Modules
  • Sitecore

The “Custom” layer is used for your custom implementation configuration files and customizing existing Sitecore standard configuration files. The Custom area folder in the App_Config is called “Include”.

The “Environment” layer is used for dividing configurations into environment specific configurations (Development, QA, Production etc).

The “Modules” layer is used for configuration files for Sitecore modules (EXM, Sitecore Publishing Service etc.).

The “Sitecore” layer is used for standard Sitecore Component configuration files (Content Search, Experience Analytics, Owin etc.).

In the Layers.config file each <layer> element has a “name” attribute and an “includeFolder” attribute defining the path to the configuration folder of the layer. The <layer> element contains a <loadOrder> element defining the load order of the configuration files specified for that specific layer. Each configuration element (patch file) is added into the <loadOrder> element and has a “path” attribute (defining the path to the configuration area) and a “type” attribute (defining whether it is a File or a Folder specific element).
<layers>
  <layer name="Sitecore" includeFolder="/App_Config/Sitecore/">
    <loadOrder>
      <add path="CMS.Core" type="Folder" />
      <add path="AntiCSRFModule" type="Folder" />
      …
    </loadOrder>
  </layer>
  <layer name="Custom" includeFolder="/App_Config/Include/" />
  …
</layers>

In case of <layer includefolder="/App_Config/Include/" name="Custom"> Sitecore loads all the configuration files placed in the “Include” folder. By default, Sitecore loads the configuration files as in previous versions of Sitecore (first, Sitecore reads the files in the root of the “Include” folder alphabetically. Secondly, Sitecore loads the configuration files alphabetically in order of the subfolders alphabetically). This, because no load order has been specified. 

If you want to specify the load order of the “Custom” area configuration folders and files located in the “Include” folder, you simply add the <loadOrder> element to the layer. From here, you specify the “path” and “type” attribute to the <add> element (the patch file) E.g.:

  <layer name="Custom" includeFolder=”/App_config/Include” >
    <loadOrder>
      <add path=”MySitecoreBaslineExtensions” type=”Folder” />
      <add path=”MyCustomSolutionHttpRequestBeginExtensions” type=”Folder” />
      <add path=”Folder1/MySitecoreProcessorExtension.config” type=”File” />
    </loadOrder>
  </layer>

After loading the configurations specified in the <loadOrder> element, Sitecore loads the remaining files and folders like Sitecore normally do.

From the Layers.config file, you can disable all patch files in a specific layer or you can disable a single file/folder. This is done by adding the mode=”off” attribute to the <layer> element or at the patch file element it self.

Disabling a layer:
<layer name="Custom" includeFolder=”/App_config/Include” mode=”off”>
  <loadOrder>
    <add path=”MySitecoreBaslineExtensions” type=”Folder” />
    <add path=”MyCustomSolutionHttpRequestBeginExtensions” type=”Folder” />
    <add path=”Folder1/MySitecoreProcessorExtension.config” type=”File” />
  </loadOrder>
</layer>

Disabling a file:
  <layer name="Custom" includeFolder=”/App_config/Include”>
    <loadOrder>
      <add path=”MySitecoreBaslineExtensions” type=”Folder” />
      <add path=”MyCustomSolutionHttpRequestBeginExtensions” type=”Folder” />
      <add path=”Folder1/MySitecoreProcessorExtension.config” type=”File” mode=”off” />
    </loadOrder>
  </layer>

The default load order is Sitecore, Modules, Custom and Environment. This load order should not be changed due potential conflicts.

If you need to customize existing Sitecore configuration files best practice is still to create your own configuration files. But now you can add/place it in the Custom or Environment layers of the Layers.config file.

The Layers.config file:
  
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <layers>
    <layer includefolder="/App_Config/Sitecore/" name="Sitecore">
      <loadOrder>
        <add path="CMS.Core" type="Folder" />
        <add path="AntiCSRFModule" type="Folder" />
        <add path="Owin" type="Folder" />
        <add path="Owin.Authentication" type="Folder" />
        <add path="ContentSearch" type="Folder" />
        <add path="ContentSearch.Azure" type="Folder" />
        <add path="Marketing.Xdb.Sql.Common" type="Folder" />
        <add path="XConnect.Client.Configuration" type="Folder" />
        <add path="Marketing.Xdb.ReferenceData.Service" type="Folder" />
        <add path="Marketing.Xdb.ReferenceData.SqlServer" type="Folder" />
        <add path="Marketing.Xdb.ReferenceData.Client" type="Folder" />
        <add path="Marketing.Operations.xMgmt" type="Folder" />
        <add path="Marketing.Operations.Xdb.ReferenceData" type="Folder" />
        <add path="Marketing.xDB" type="Folder" />
        <add path="Marketing.Tracking" type="Folder" />
        <add path="Marketing.Assets" type="Folder" />
        <add path="Tracking.Web.RobotDetection" type="Folder" />
        <add path="Mvc" type="Folder" />
        <add path="Tracking.Web.MVC" type="Folder" />
        <add path="ItemWebApi" type="Folder" />
        <add path="Buckets" type="Folder" />
        <add path="SPEAK" type="Folder" />
        <add path="Services.Client" type="Folder" />
        <add path="SPEAK.Components" type="Folder" />
        <add path="Marketing.Client" type="Folder" />
        <add path="Marketing.Xdb.MarketingAutomation.Reporting" type="Folder" />
        <add path="Marketing.Xdb.MarketingAutomation.Operations" type="Folder" />
        <add path="Marketing.Xdb.MarketingAutomation.Locators" type="Folder" />
        <add path="Marketing.Xdb.MarketingAutomation.Tracking" type="Folder" />
        <add path="XConnect.Segmentation.xMgmt" type="Folder" />
        <add path="Speak.Applications" type="Folder" />
        <add path="LaunchPad" type="Folder" />
        <add path="ListManagement" type="Folder" />
        <add path="Marketing.Automation.Client" type="Folder" />
        <add path="Marketing.Automation.ActivityDescriptors.Client" type="Folder" />
        <add path="ExperienceForms" type="Folder" />
        <add path="Experience Editor" type="Folder" />
        <add path="MVC.ExperienceEditor" type="Folder" />
        <add path="MVC.DeviceSimulator" type="Folder" />
        <add path="ContentTesting" type="Folder" />      
        <add path="ExperienceProfile" type="Folder" />
        <add path="Update" type="Folder" />
        <add path="Contact.Enrichment.Services.Client" type="Folder" />
        <add path="DetectionServices.Location" type="Folder" />
        <add path="FederatedExperienceManager" type="Folder" />
        <add path="DeviceDetection.Client" type="Folder" />
        <add path="ExperienceAnalytics" type="Folder" />
        <add path="CampaignCreator" type="Folder" />
        <add path="ExperienceContentManagement.Administration" type="Folder" />
      </loadOrder>
    </layer>
    <layer includefolder="/App_Config/Modules/" name="Modules" />
    <layer includefolder="/App_Config/Include/" name="Custom" />
    <layer includefolder="/App_Config/Environment/" name="Environment" />
  </layers>
</configuration>



Sitecore Application_Start and <initialize> Pipeline

For some time ago, I needed to build up some cache on Sitecore application start up. Sure, in a clean web application I could use the Global.asax, but in the world of Sitecore, the Global.asax has been made private. Instead of changing the Global.asax file, you should use the initialize pipeline. The initialize pipeline is started at application start (you find the initialize pipeline in Sitecore.config).

In this case of building up some caching on Sitecore application start, I create a new config include file and add the my new processor:
 
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
<pipelines>
    <initialize>
      <processor type="MyExtensions.Pipelines.Caching.CachePrefill, MyExtensions" xdt:Transform="Insert" />
    </initialize>
  </pipelines>
</Sitecore>
</configuration>

Do the coding. Notice, you don’t need to inherit from any other namespaces. 
namespace MyExtensions.Pipelines.Caching
{
    public class CachePrefill
    {
        public void Process(PipelineArgs args)
        { 
            Sitecore.Diagnostic.Log.Info("MyExtensions: Running CachePrefill.Process method", this);
            
            //do my magic cachePrefill();
            
            Sitecore.Diagnostic.Log.Info("MyExtensions: Done running CachePrefill.Process method", this);
        }
    }
}

Nothing more, nothing less.