SiteSettings for your Epi Site
A neat way to configure site settings with DI StructureMap in Episerver
Published 2nd sept 2020
I like this approach, site settings thru Dependency Injection (DI). Im fully aware that this subject is nothing new, and EMVP collegues have been blogged about this for ages.
Arild: https://www.epinova.se/nyheter-och-blogg/utvecklarbloggen/2016/configuration-options-for-episerver-sites/
Maris: https://marisks.net/2020/03/31/managing-settings-in-episerver-project-3/
Mathias: https://blog.mathiaskunto.com/2016/09/29/easy-way-to-manage-global-settings-in-multilanguage-episerver-website/
Linus: https://github.com/LinusEkstrom/AddOn.Episerver.Settings
However, none are using Interface and DI to locate the settings (except Linus’ addon, but thats another approach).
Usage
Example 1 – preferable
public FeatureFlagService(ISiteSettings siteSettings) { _siteSettings = siteSettings; }
Example 2 – get StartPage as ISiteSettings
siteSettings = IContentLoader.Get<ISiteSettings>(SiteDefinition.Current.StartPage, LanguageSelector.AutoDetect());
//Rule two, from site settings
if (siteSettings.NewFeatureEnabled)
_flag1 = siteSettings.NewFeatureEnabled;
Example 3, multiple ISiteSettings in one site
var startPage = repository.GetClosest(currentPage);
Make an Interface ISiteSettings
namespace AlloyTemplates.Business { public interface ISiteSettings : IContent { bool NewFeatureEnabled { get; set; } } }
Add your settings properties into this Interface
SiteSetting needs to derive from IContent since you later want to use the contentLoader to load ISiteSettings
Implement Interface as a Partial class
What you need is to put key word “partial” into both object implementation, important to use same class name in same namespace.
[ContentType(GUID = "x")]
public partial class StartPage : SitePageData, IContent
and
public partial class StartPage : ISiteSettings { [Display(GroupName = Global.GroupNames.SiteSettings, Order = 1)] public virtual bool NewFeatureEnabled { get; set; } }
Note: It is the StartPage that is derived from PageData that implements IContent and not the StartPage.ISiteSettings
Register ISiteSettings to StructureMap with Registry
public class SiteSettingsRegistry : Registry { ///Exposed as internal to enable usage from test class library internal static FuncLangSelector = LanguageSelector.AutoDetect; public SiteSettingsRegistry() { For ().HybridHttpOrThreadLocalScoped().Use(context => GetSiteSettings(context, LangSelector())); } private static ISiteSettings GetSiteSettings(IContext context, LanguageSelector languageSelector) { var contentLoader = context.GetInstance (); return contentLoader.Get (ContentReference.StartPage, languageSelector); } }
The Registry will be scanned and configured if you configure StructureMap with a IConfigurableModule like this:
[InitializableModule] public class DependencyResolverInitialization : IConfigurableModule { public void ConfigureContainer(ServiceConfigurationContext context) { //Implementations for custom interfaces can be registered here. context.StructureMap().Configure( x => { x.Scan(y => { y.TheCallingAssembly(); y.LookForRegistries(); y.WithDefaultConventions(); }); }); } }
Multisite scenario
Yes! by using ContentReference.StartPage in registry or SiteDefinition.Current.StartPage it will contextualy return the right settings.
Note: remember to set * in website management i Epi Admin to assign the default website if no HttpContext exists (in scheduled jobs ContentReference.StartPage will return the default website startpage if * is configured)
About the author
Luc Gosso
– Independent Senior Web Developer
working with Azure and Episerver
Twitter: @LucGosso
LinkedIn: linkedin.com/in/luc-gosso/
Github: github.com/lucgosso