Application Settings
Application settings let you store configurable values — like feature flags, default numbers, API credentials, or complex option groups — that administrators can change at runtime without redeploying code. Think of them as a key-value store that is strongly typed, editable through the Shesha UI, and accessible from both back-end and front-end code.
When to use settings:
- You need a value that might change between environments or over time (e.g. a default debit day, an SLA duration, a toggle to enable/disable a feature).
- You want administrators to adjust behaviour from the Settings UI without involving a developer.
- You need user-specific preferences (e.g. notification frequency).
Key Concepts
Before diving in, here are the building blocks you'll work with:
| Concept | What it is |
|---|---|
| Setting accessor interface | A C# interface (extending ISettingAccessors) that declares your settings as strongly typed properties. By convention, each Shesha module has one accessor interface — see Organizing settings below. |
ISettingAccessor<T> | The property type for each setting. T is the data type — int, bool, string, or a custom class for compound settings. |
| Setting name | A unique string identifier for each setting (e.g. "Shesha.Membership.DebitDay"). |
| Module registration | A one-line call in your module's Initialize (or PreInitialize) method that tells Shesha about your settings and their default values. |
Organizing settings
Use a single setting accessor per module. Having one interface centralizes all your module's settings in one place, making them easy to find, inject, and maintain. Place it at:
YourModule.Domain/
Configuration/
IMembershipSettings.cs ← accessor interface
MembershipSettingNames.cs ← setting name constants
MembershipPaymentSettings.cs ← compound setting classes (if any)
The naming convention is I{ModuleName}Settings.cs. For example, a module called Membership would have IMembershipSettings, a module called Leave would have ILeaveSettings, and so on.
You can create more than one accessor interface per module if you have a good reason — for example, separating global settings from user-specific settings, or isolating a large, self-contained feature area. But start with one and only split when a single interface becomes unwieldy.
Simple vs. compound settings
Shesha supports two styles of settings, and compound settings are generally preferred:
- Simple settings — a single primitive value (
int,string,bool). Good for standalone toggles or numbers that don't relate to other settings. - Compound settings — a custom class containing multiple related properties. This is the recommended approach for most cases because:
- Grouping — related values stay together (e.g. all payment-related settings in one object), making the code easier to understand.
- Efficiency — multiple related values are retrieved in a single call instead of one call per setting.
- Richer UI — compound settings use a custom editor form, giving you full control over the layout, validation, and user experience for administrators.
When in doubt, use a compound setting. Even if you start with just two or three related values, a compound setting scales better as requirements grow.
Creating a Simple Setting
A "simple" setting stores a single value — a number, a string, a boolean, etc. We'll walk through creating a Debit Day setting that controls which day of the month a membership payment is processed.
Step 1 — Define setting names
In your Domain layer, create a Configuration folder and add a class to hold your setting name constants:
namespace YourApp.Domain.Configuration
{
public class MembershipSettingNames
{
public const string DebitDay = "Shesha.Membership.DebitDay";
}
}
Using constants avoids typos and makes it easy to reference the same name everywhere.
Step 2 — Define the setting accessor interface
In the same Configuration folder, create an interface that extends ISettingAccessors. Each property represents one setting. Following the one-accessor-per-module convention, name it I{ModuleName}Settings:
using Shesha.Settings;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace YourApp.Domain.Configuration
{
[Category("Membership")]
public interface IMembershipSettings : ISettingAccessors
{
[Display(Name = "Debit day", Description = "Day of the month when membership payments are debited.")]
[Setting(MembershipSettingNames.DebitDay)]
ISettingAccessor<int> DebitDay { get; set; }
}
}
What the attributes do:
| Attribute | Purpose |
|---|---|
[Category("Membership")] | Groups this setting under "Membership" in the Settings UI. Can be applied at the interface or property level. |
[Display(Name, Description)] | Sets the label and tooltip shown in the Settings UI. |
[Setting(...)] | Links the property to its unique setting name. Also supports optional flags — see Setting attribute options below. |
Step 3 — Register the accessor in your module
Open your module class (the class that extends SheshaModule) and register the setting accessor. This is also where you provide a default value:
public override void Initialize()
{
var thisAssembly = Assembly.GetExecutingAssembly();
IocManager.RegisterAssemblyByConvention(thisAssembly);
// Register settings with default values
IocManager.RegisterSettingAccessor<IMembershipSettings>(x =>
{
x.DebitDay.WithDefaultValue(1);
});
}
The default value (1) is used when no value has been saved yet — in this case, payments default to the 1st of each month.
Step 4 — Verify in the UI
Run your back-end, then navigate to Configurations > Settings in the Shesha UI. You should see the new Debit day setting under the Membership category:

Setting values are managed here, in the Application Settings screen. This is separate from the Configuration Studio, where settings are defined (in code or configuration). Use the Studio to declare a setting, and this screen to view or change its value.
That's it — you have a working application setting.