So long story short. We all know and use (right?) the established Sitecore Best Practice for not modifying vanilla configuration files. We use
config patches (or
config overrides, as some call them) to add new settings and patch existing ones.
Just so there is no misunderstanding here; this is the type of setting I'm talking about:
<setting name="AllowDuplicateItemNamesOnSameLevel" value="true" />
These all sit under the
<sitecore><settings> element and is therefore under the control of the Sitecore Configuration Factory and can thus be patched by config include files that Sitecore loads up dynamically when the factory initialises.
GetSetting() is a
public static. So there, our challenge is laid out before us.
What I would like to achieve is a way, so these defined settings (patched or vanilla) would get "overruled" if a similarly named setting had been defined by a regular
<appSettings> value. And I would like this to be injected in, somehow - shielded from the rest of the application.
The significance of
The reason for this, I should add, is Azure. And for running Sitecore on
Azure PaaS. As you may or may not be aware, any WebApp running on Azure can have instance/slot specific configuration settings defined in the Azure Portal. It looks like this.
These settings will override any
<appSettings> defined in your web.config, and the connection strings will do the same. But it only works for this; not for the Sitecore flavoured settings.
Now I'm not saying all settings should be pushed to the portal. But some, definitely make sense. Any server-to-server connection settings, service bus connection strings, mail servers and so on.
My progress so far
So to try and implement this; I've done what I must. I've opened up dotPeek and taken a look around ;-)
The real work is done in a
private static GetWebSettings() method. In short, it maintains an internal
Hashtable for all settings, and will loop through all
settings/setting XML elements for settings and values. Given that it's a
private static, the only way to override it would be some form of method replacement via reflection. While possible, it's not the prettiest of approaches and I'd rather avoid it.
So the question is; where would be the best (err.. least likely to break/cleanest/least invasive) place to inject code that would allow these settings to be overridden by Azure? I haven't written that code yet, but something to the effect of this:
var setting = GetSettingFromSitecore(settingName); if (Azure.Settings[settingName]) setting = Azure.Settings[settingName];