Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Requires: abstractions module, main module (constraints).
Validation feature allows to associate a custom user-made validator with a settings type. Validation occurs during binding and results in binding errors for incorrect settings.
There are also built-in validation constraints you can use to create a custom validator. Just inherit your validator class from ConstraintsValidator
and override a method returning constraints to be checked:
Here's a list of all currently implemented constraint types:
NotNullConstraint
for arbitrary reference types;
NotNullOrEmptyConstraint
for strings;
NotNullOrWhitespaceConstraint
for strings;
RangeConstraint
, LessConstraint
, LessOrEqualConstraint
, GreaterConstraint
and GreaterOrEqualConstraint
for any types that implement IComparable
;
UniqueConstraint
to check that a set of field/properties only contains unique values;
Requires: abstractions module.
This extension point covers scenarios where existing binders are not sufficient to handle required types.
Custom binders should be used as a last resort when constructor injection and parsing conventions are not powerful enough.
Creating a binder for a type is just a matter of implementing an interface:
Custom binders can be applied to specific fields and properties or whole types:
Requires: main module.
Configuration provider class has a property named Default
that serves as a global static source of IConfigurationProvider
instance.
It's intended use case is self-sufficient configuration in libraries: library authors may not want to force their users to provide an IConfigurationProvider
instance each time they're using library classes. Instead, these classes could just obtain a log from the shared property:
By default this property returns a singleton provider with default settings. It can be configured explicitly in the application:
Requires: abstractions module.
Name aliases provide alternative keys to look for in settings nodes when performing binding.
They can be applied to fields and properties with a special attribute:
It's allowed to assign multiple aliases to a single member:
Aliases do not handle ambiguity. If the source returns data with more than one of the lookup keys assigned to a field or property, binding fails with an error.
Requires: sources module.
This operation allows to effectively disable data updates on a source:
Requires: sources module.
Sources module offers a couple of base classes to assist in implementing custom configuration sources.
For in-memory sources or sources that can update an in-memory one from a remote API.
For sources based on local files. Includes automatic reload on file updates.
Requires: sources module.
This operation allows to embed source's data into a nested object section:
Requires: sources module.
This operation allows to modify source contents by applying a custom delegate. Most often this involves rewriting values stored in value nodes:
Requires: sources module.
Value substitution feature allows to replace placeholders in settings data. It's based on the transformation extensions and uses #{}
syntax for placeholders.
Requires: , .
Requires: main module.
The basic recommended way to get most up-to-date settings in the presence of background updates is to use provider's Get method (see the relevant scenario) on each access attempt. However, it's also possible to obtain an inherently dynamic settings object whose properties are updated under the hood. This requires to use an interface as the settings model:
Note that in order to get a guaranteed consistent view of the settings without "tearing" (observing a mix of values from before and after update due to a race condition) when using a nested object (section), it's recommended to access a snapshot of this nested object saved in a variable: