Friday, 5 February 2016

Sitecore Configuration Best Practices

What is Sitecore configuration ? How does it work ?

Sitecore CMS platform extensibility is mainly provided by a large set of configuration (providers, event subscribers, index definitions, settings and etc.).

Sitecore running configuration is read from web.config and combined with configuration files ( *.config) from '\App_Config\' folder.

Building resulting Sitecore configuration


The configuration is built via following steps:

  1. Read 'web.config' file
  2. Process 'App_config' folder nested configs & folders
  3. Process 'Include' folder configs in alphabetical order
  4. Process ''Include' folder nested folders content in alphabetical order
Building resulting configuration

Example

  1. web.config defines <setting name="CustomSetting" value="web.config value"/>
  2. AA.config patches <setting name="CustomSetting" set:value="AA"/>
  3. AB.config patches <setting name="CustomSetting" set:value="AB"/>
When order matters
Resulting value is taken from last alphabetical patch AB.config:

 <setting name="CustomSetting" value="AB" patch:source="AB.config" />

Summarize

  • Alphabetical order MATTERS-> Sitecore.A.config would be applied before Sitecore.B.config
  • If you want a config to be applied 100500%, put it into last alphabetical folder with last alphabetical name (f.e. 'zzz' folder with 'zzz.config' name)

Using resulting configuration inside Sitecore CMS 

Why ?

Aggregated configuration is used to:
  1. Create a lot of objects via reflection (f.e. Sitecore.Configuration.Factory.CreateObject API)
  2. Set cache sizes
  3. Construct pipelines, indexes
  4. Read setting values (f.e. Sitecore.Configuration.Settings.GetSetting("key","defaultValue")
  5. Process Sitecore Events & subscriptions

How to use configuration in code ? 

There are 2 main classes that encapsulate configuration-related logic:
  • Sitecore.Configuration.Factory static class allows to get config sections, create objects from config nodes
  • Sitecore.Configuration.Settings static class allows to get value of setting defined inside configuration with a fallback to default value
    • Meaning if value is not defined in resulting configuration, a fallback one would be taken (f.e. Settings.GetSetting("NotDefinedSetting", "DefaultValue") )
    • One can easily add custom setting (key-value pair) under sitecore/configuration/settings node, and value would be available via aforementioned API. 

Example

Configuration patch

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
   <settings>
    <setting name="CustomSetting" value="CustomValue"/>
   </settings>
  </sitecore>
</configuration>

Reading value from patch

Following API is to be used in order to get value in runtime:

string value = Sitecore.Configuration.Settings.GetSetting("CustomSetting", "DefaultValue")

There are other methods in the Sitecore.Configuration.Settings class that should be mentioned:
Hidden setting (not in stock web.config) with default value 'True'
  • GetBoolSetting
  • GetIntSetting
  • GetTimeSpanSetting
  • GetLongSetting

Fetching whole configuration at once

Resulting XML configuration from running Sitecore can be received via :
  • 'Sitecore.Configuration.Factory.GetConfiguration()' API
  • Requesting '[hostname]\sitecore\admin\showconfig.aspx' page
The resulting document would have only '<Sitecore>' section inside, and would NOT have native ASP.NET sections =\

Build resulting configuration WITHOUT running Sitecore CMS

To ensure that Sitecore would pick your configuration changes correctly, you can use standalone application that emulates Sitecore config building - > Sitecore ConfigBuilder application.

It would use same logic as Sitecore CMS, and produce exactly same resulting configuration.

Why ? When ?


  1. Every config change provokes CMS restart. It could introduce additional time costs during patch tuning
  2. Stock 'showconfig' skips ASP.NET <system.web> and <system.WebServer> sections, whereas ConfigBuilder includes sections.
  3. Sitecore CMS may not start due to problems with configuration ( type not found, or node is missing ), and you will not be able to see 'faulting' configuration =\
  4. Config normalization ( removing XML comments, ordering ) simplifies further comparison


Developing patches

Include File Patching Facilities documentation highlights general rules on HowTo develop configuration patches (f.e. replace stock processor with a custom one, change setting value, remove event handler, and etc.)

Alexander Lebedenko has developed an awesome ConfigPatcher tool to automatize the config patching developing process. Though the UI is friendly, an image shows a set of needed steps to generate config patch file.

Config Patcher sample steps

Patching best practices


Never modify web.config file

It will save tons of your time during upgrading Sitecore solution. An upgrade procedure will likely come with a new version of web.config with extra nodes.

Sitecore Updater tool would detect changes in web.config and would NOT replace it with newer version.

You will have to manually copy modified nodes into web.config.
You could simplify an upgrade by using configuration patches instead.

Maintain baseline

Generate resulting configuration BEFORE applying patch and use it as base configuration version.

Generate a new resulting configuration AFTER applying configuration patch.

Use WinMerge tool to ensure that all needed changes are applied correctly.


Transfer patch to live Sitecore ONLY after verifying changes

Transfer patch to production environment only after verifying that patch changes configuration correctly.