Skip to content

Application Configuration

Ioan Crisan edited this page Oct 13, 2017 · 11 revisions

The application configuration

A primitive ambient service is the IAppConfiguration, which is an expando object.

  • The indexer returns or sets the configuration sections.
  • Additionally, the GetSettings<TSettings>([section name]) extension method provides a simple way of accessing typed sections, with the following conventions:
    • If the section name is not provided, the section name is considered the name of the TSettings type without the Settings ending, if any.
    • The section settings is retrieved as appConfiguration[sectionName] after which the result is converted to TSettings, either directly, if possible, or by creating a TSettings object to which the properties are set based on the (key, value) pairs in the section.

Note: It is not registered through the [SharedAppServiceContract] because it is used by the composition before constructing the dependency injection container, so it needs to be available prior to building the container.

By default, the DynamicAppConfiguration is registered in the ambient services, which is a service providing for every requested section an empty expando object.

A useful extension method is GetAppSettings() or GetAppSettings<TSettings>() which provides access to the appSettings section. This may be particularly important when working with the app.config/web.config files, like described below.

App.config/Web.config based configuration

The default DynamicAppConfiguration does not help much a real world application, considering that typically the configuration is done by using the app.config/web.config files. For this scenario, it is recommended to use the DefaultAppConfiguration, which bases on those files, and the sections are retrieved from the sections in those files.

    // add a reference to the Kephas.Platform package
    var ambientServicesBuilder = new AmbientServicesBuilder();
    ambientServicesBuilder
        .WithDefaultAppConfiguration();

Component-based configuration

The IConfiguration<TSettings> service

While the application configuration should be fine for most cases, when working very strictly component oriented it would be more appropriate to access a configuration targeted to that component, if possible injected through composition. This is possible through the IConfiguration<TSettings> shared application service.

  • This service is itself an expando object, where values may be dynamically added.
  • Provides the Settings: TSettings property, which returns the settings of the specified type.

Example of usage:

    // Settings class (DTO)

    public class ConsoleSettings
    {
        public string ForeColor { get; set; }

        public string BackColor { get; set; }
    }

    // Class consuming IConfiguration<ConsoleSettings>.

    public class ConsoleFeatureManager : FeatureManagerBase
    {
        private readonly IConfiguration<ConsoleSettings> consoleConfig;

        public ConsoleFeatureManager(IConfiguration<ConsoleSettings> consoleConfig)
        {
            this.consoleConfig = consoleConfig;
        }

        /// <summary>Initializes the feature asynchronously.</summary>
        /// <param name="appContext">Context for the application.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A Task.</returns>
        protected override async Task InitializeCoreAsync(IAppContext appContext, CancellationToken cancellationToken)
        {
            Console.BackgroundColor = Enum.Parse<ConsoleColor>(this.consoleConfig.Settings.BackColor);
            Console.ForegroundColor = Enum.Parse<ConsoleColor>(this.consoleConfig.Settings.ForeColor);
        }
    }

The Configuration<TSettings> service implementation

This service implementation is the default for the IConfiguration<TSettings> service contract. It is designed to be truly flexible in providing settings of a specific type, by aggregating configuration providers aimed at specific settings types and to which it delegates the settings retrieval. To summarize the flow:

  • Gets the configuration providers ordered by their override and processing priority.
  • Tries to find a provider handling that specific settings type. If none found, then it looks for another provider handling a compatible settings type. If still none found, then attempts to find one handling all settings types. If still none found, a NotSupportedException occurs.
  • Delegates the settings retrieval to that provider.
  • Caches the settings for faster later use.

Configuration providers

As described previously, the configuration providers are used to provide settings of a specific type. They are completely free in choosing the proper implementation. A fallback provider is the AppConfigurationProvider, which is registered for all settings type, however with the lowest priority, and which gets the settings from the IAppConfiguration service.

A configuration provider:

  • declares the handled settings type over the [SettingsType(type)] attribute.
  • provides the settings through the GetSettings(settingsType: Type): object method.

Another typical configuration provider would be a file based one, for example JSON or XML.

Clone this wiki locally