Configuration

Application configuration framework

Overview

Configuring an application is usually done by the user via the Configuration / Settings UI in the backend. The optional forms are provided by each module to ensure data validity and prevent unwanted changes. At the lowest level, each individual setting is just a record in the database represented by the Setting entity. The value of which is stored as plain text in the Value field.

To make things easy to work with, settings are grouped and combined into POCO classes. Here are some examples:

Technical concept

Every settings class needs to implement the ISettings interface and must have a public constructor without parameters. Each property in the class represents an individual setting which name in the database is a combination of the class and property name. That means that the DefaultTheme property in the ThemeSettings class would be: ThemeSettings.DefaultTheme.

The settings database value is the string representation of the property value, which means that the property type must be convertible to and from a string. Only public properties with a getter and a setter are eligible as persistent settings. All other properties (or members in general) are ignored.

The application's own type conversion system is used to convert between types.

Setting entries are multi-store enabled and an entry's value can optionally be overwritten on store level.

Accessing settings

By Dependency Injection

The simplest and most widely used pattern for accessing settings is to pass them around as dependencies. A special component registration source dynamically registers all classes that implement ISettings as singleton dependencies.

By ISettingFactory

The singleton ISettingFactory is responsible for activating and populating setting class instances that implement ISettings.

The method for loading settings is LoadSettingsAsync<TSettings>(). It tries to load TSettings for a given store from cache or from database, if it’s not yet cached. Similarly the method for saving settings is SaveSettingsAsync<TSettings>(). It saves a settings instance for a given store in the database.

Accessing individual setting entries

You can also access individual entries by using the ISettingService. Updating individual entries automatically invalidates the classes cache. For example, all ThemeSettings instances are removed from the cache when the ThemeSettings.DefaultTheme entry is updated or deleted.

You are not restricted to setting classes. Any setting entry can be created and accessed, without being part of a setting class.

Tutorial

The following code shows how to provide custom settings with a full-blown multi-store enabled editor. It also provides some useful code for a pseudo Blog module.

Create settings class

Create settings model

While not required, separating user interface and application layers is good practice. Create a view model for BlogSettings to do so.

Refer to:

  • Data modelling for more info about modelling in Smartstore.

  • Localization to learn more about the LocalizedDisplay attribute.

  • Validation to learn how to validate your model on form post.

Create view

Create controller actions

Decorate the GET action with the LoadSetting attribute and the POST action with the SaveSetting attribute. These are not required, but they will save you from having to write tedious, repetitive code.

The LoadSetting attribute resolves all setting class action parameters automatically from Dependency Injection (in this case BlogSettings) and passes them on to the method. If one is specified, the int storeScope parameter will also be filled with the current store id.

The SaveSetting attribute does roughly the same, including:

  • Patch model parameters according to the current store scope and omit properties that have not been overwritten.

  • Saving the setting instance to the database.

Refer to:

Create menu item

There are many ways to hook your settings page into the backend.

Please refer to Menus to learn about the menu system and how to hook in.

Last updated

Was this helpful?