SiteSettings for your Epi Site

A neat way to configure site settings with DI StructureMap in Episerver

icon of user profile

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

Use C# Partial Class to separate the startpage properties from the SiteSettings properties into two files

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 Func LangSelector = 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