Architecture

Multisite configuration management with an Enterprise Accelerator

Abstract Runner@1x.jpg

One major consideration you have to make when building an enterprise layer is the flexibility of the component library itself. The components and functions provided by your enterprise layer have to be created in a tenant-agnostic way. This means that they should not understand the tenant layer (aka project layer in Helix terms) or which website may be using them. They simply exist to serve the tenants.

One easy trick that I’ve been using across many of my projects is allowing for the generic Enterprise components to allow for a configuration fallback.

Configuration Fallback

Let me explain. The idea is simple. At the enterprise layer, I want to provide a default configuration value that may be stored in a configuration file. Let’s assume this configuration value is for an API Key for the FooBar service:

 

<sitecore>
<settings>
<setting name="FooBar.ApiKey" value="XYZ" />
</settings>
</sitecore>

Given that we’ve set this up, we can write code like this to extract it:

var setting = Sitecore.Configuration.Settings.GetSetting("FooBar.ApiKey");
// setting is "XYZ"

So, assuming that I’m making a generic component that uses this API Key, how can I handle this configuration setting being a different value per-tenant?

The solution is Configuration Fallback.

Covid 19
COVID-19: Digital Insights For Enterprise Action

Access Perficient’s latest insights into how you can leverage digital technologies to not only respond to the pandemic, but drive your operations forward and deliver experiences your customers need.

Get Informed

To pull this off, it’s quite simple. I will introduce configuration that looks like this:

 

<sitecore>
<settings>
<setting name="AcmeCo.Alpha.FooBar.ApiKey" value="ABC" patch:source="Project.Alpha.config" />
<setting name="AcmeCo.Gamma.FooBar.ApiKey" value="123" patch:source="Project.Gamma.config" />
<setting name="AcmeCo.Enterprise.FooBar.ApiKey" value="XYZ" patch:Source="Foundation.FooBar.config" />
</settings>
</sitecore>

Notice that the Alpha and Gamma sites have introduced a custom setting, while the Enterprise layer provides a default setting from Foundation.FooBar.config. All settings files are named intelligently to help with quick debugging when glancing at /sitecore/admin/showconfig.aspx.

To implement the configuration fallback, I introduce a service that all layers can utilize:

 

namespace Enterprise.Configuration.Services
{
public interface IConfigurationManager
{
string GetSetting(string settingName);
}

public class ConfigurationManager : IConfigurationManager
{
public string GetSetting(string settingName)
{
var organization = "AcmeCo"; // replace with your convention as necessary

var siteName = Sitecore.Context.Site?.Name;

if (siteName != null)
{
var localSetting = Sitecore.Configuration.Settings.GetSetting($"{organization}.{siteName}.{settingName}");
if (localSetting != null)
return localSetting;
}

var enterpriseSetting = Sitecore.Configuration.Settings.GetSetting($"{organization}.Enterprise.{settingName}");
if (enterpriseSetting != null)
return enterpriseSetting;

return Sitecore.Configuration.Settings.GetSetting(settingName);
}
}
}

Which results in this:

var configManager = new ConfigurationManager(); // we'll cover injecting dependencies next

// Assuming that Sitecore.Context.Site is Alpha:
var setting = configManager.GetSetting("FooBar.ApiKey"); // resolves to "ABC"

// Assuming that Sitecore.Context.Site is Gamma:
var setting = configManager.GetSetting("FooBar.ApiKey"); // resolves to "123"

// For any site that doesn't explicitly call out this config value:
var setting = configManager.GetSetting("FooBar.ApiKey"); // resolves to "XYZ" as the 'enterprise default'

In doing this, I’ve now created a foundational element that all components can use. Remember: your Enterprise components should not have any logic directly related to a tenant website. Instead, you can utilize configuration injection techniques to resolve dependencies and settings at runtime!

Bonus

You can also attach settings to your site definition and fallback to this if you choose.

For instance, assuming that my site definition looks like this:

 

<sitecore>
<sites>
<site name="Alpha" ... FooBar.ApiKey="ABC" />
</sites>
</sitecore>

I can then extract this configuration via this code:

var setting = Sitecore.Context.Site.Properties["FooBar.ApiKey"];

Happy coding!

About the Author

I am a certified Sitecore developer, code monkey, and general nerd. I hopped into the .NET space 10 years ago to work on enterprise-class applications and never looked back. I love building things—everything from from Legos to software that solves real problems. Did I mention I love video games?

More from this Author

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to the Weekly Blog Digest:

Sign Up