[ASP.NET Core 3 framework Secret] Configuration [6]: diverse configuration source [Part I]

One of the main features of this new model of .NET Core configuration is used to support a variety of different configurations sources. We can be memory variables, command-line arguments, environment variables, and physical file as the original configuration data sources. If the physical configuration file as the source, we may choose a different format (such as XML, JSON and INI, etc.). If the default configuration source in the form of support can not meet your needs, we can also customize the way by registering the IConfigurationSource other forms of data as a source configuration.

一、MemoryConfigurationSource

In the previous examples demonstrate are using MemoryConfigurationSource to provide original configuration. We know MemoryConfigurationSource source configured using a dictionary object (a particular element should be of type KeyValuePair <string, string> set) is stored as configuration data of the original container. As a IConfigurationSource object, it is always to complete specific configuration data read work by creating a corresponding IConfigurationProvider object, MemoryConfigurationSource will provide a kind of IConfigurationProvider it?

public  class MemoryConfigurationSource: IConfigurationSource
{
    public IEnumerable<KeyValuePair<string, string>> InitialData { get; set; }
    public IConfigurationProvider Build(IConfigurationBuilder builder) => new MemoryConfigurationProvider(this);
}

Snippet given above embodies MemoryConfigurationSource complete definition, we can see that it has a IEnumerable <KeyValuePair <string, string >> type attribute InitialData to store the initial configuration data. As can be seen from the implementation Build method, which was actually used to read the original configuration data objects is a MemoryConfigurationProvider type, the type as defined in the following code fragment.

public class MemoryConfigurationProvider : ConfigurationProvider,  IEnumerable<KeyValuePair<string, string>>
{
    public MemoryConfigurationProvider(MemoryConfigurationSource source);
    public void Add(string key, string value);
    public IEnumerator<KeyValuePair<string, string>> GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator();
}

As can be seen from the above code fragment, MemoryConfigurationProvider derived from the abstract class ConfigurationProvider, while also achieving a IEnumerable <KeyValuePair <string, string >> interface. We know ConfigurationProvider object directly using a Dictionary <string, string> to save the configuration data, according to the time when we call a MemoryConfigurationSource Object constructor to create MemoryConfigurationProvider, it only needs to be transferred to this dictionary through the configuration data can be saved properties InitialData . Add MemoryConfigurationProvider also defines a method so that we can can add a new configuration to configure the dictionary at any time.

By earlier description of the configuration model, we know IConfigurationProvider configuration object model is the role reads the original configuration data and converts it to configure the dictionary . In all achieve predefined IConfigurationProvider types, MemoryConfigurationProvider the most simple and direct, because it corresponds to the configuration of the source configuration is a dictionary, so there is no need to make any structural transformation.

When using the MemoryConfigurationSource build configuration, we need to register it onto IConfigurationBuilder object. Specifically, we can be like the previous examples demonstrate, like directly call the Add method IConfigurationBuilder interface, you can also call AddInMemoryCollection two overloaded extension method as shown below.

public static class MemoryConfigurationBuilderExtensions
{
    public  static IConfigurationBuilder AddInMemoryCollection (   this IConfigurationBuilder configurationBuilder);
    public  static IConfigurationBuilder AddInMemoryCollection (   this IConfigurationBuilder configurationBuilder, IEnumerable <KeyValuePair < string , string >> initialData);
}

二、EnvironmentVariablesConfigurationSource

As the name suggests, it is to describe the current environment variables affect the execution environment and execution behavior of process variables. According to different scopes, we set the environment variable is divided into three categories, namely for the current system, the current user environment variables and the current process. For Windows systems, system and user-level environment variable is stored in the registry, its path are "HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ Control \ Session Manager \ Environment" and "HKEY_CURRENT_USER \ Environment".

Extract and preserve the environment variables can be done by static type Environment. Specifically, we can call its static method GetEnvironmentVariable get the value of a specified environment variable name, and GetEnvironmentVariables method will return all the environmental variables, EnvironmentVariableTarget storage location enumeration type parameter represents the environment variable scoping decision. If you do not when you call GetEnvironmentVariable or GetEnvironmentVariables method explicitly specify the target parameter or specify parameters for EnvironmentVariableTarget.Process, all environment variables exist before the initialization process (including the system for the current user and the current process) will serve as the candidate list.

public static class Environment
{
    public static string GetEnvironmentVariable(string variable);
    public static string GetEnvironmentVariable(string variable,  EnvironmentVariableTarget target);

    public static IDictionary GetEnvironmentVariables();
    public static IDictionary GetEnvironmentVariables( EnvironmentVariableTarget target);

    public static void SetEnvironmentVariable(string variable, string value);
    public static void SetEnvironmentVariable(string variable, string value,  EnvironmentVariableTarget target);
}

public enum EnvironmentVariableTarget
{
      Process,
      User,
      Machine
}

Add environment variables, modify, and delete methods by SetEnvironmentVariable to complete, if not explicitly specified target parameters, the default is used in EnvironmentVariableTarget.Process. If you want to remove an environment variable to specify the name, we only need to call this method when the value of the parameter is set to Null or empty string can be.

In addition to using static type Environment in the program, we can also use the command line to view and set the environment variable. In addition, we are in the development environment also can use the "System Properties (System Properties)" View Settings tool to visualize the way and set up the system and user-level environment variable ( "This PC"> "Properties "> "Change Settings ">" Advanced ">" Environment Variables "). If Visual Studio to debug applications we write, we can set process-level environment variables ( "Properties"> "Debug" > "Environment Variables") set the project properties using the way. In Chapter 1, "a new development experience." As we mentioned, the environment variable settings will be saved to launchSettings.json file.

6-16、

Source configured for environment variables to represent the type defined in the NuGet package "Microsoft.Extensions.Configuration.EnvironmentVariables" in this EnvironmentVariablesConfigurationSource by type. This type defines a type attribute string Prefix, which represents the prefix environment variable name. If we set the Prefix attribute, the system will only select the name as a prefix environment variable.

public  class EnvironmentVariablesConfigurationSource: IConfigurationSource
{
    public string Prefix { get; set; }
    public IConfigurationProvider Build(IConfigurationBuilder builder)=> new EnvironmentVariablesConfigurationProvider(Prefix);
}

By snippet given above, we can see EnvironmentVariablesConfigurationSource be configured by the corresponding source object to read EnvironmentVariablesConfigurationProvider environment variables, this is reflected in the Load method shown below. As the environment variable itself is a data dictionary, so EnvironmentVariables
ConfigurationProvider objects no longer need to convert the structure. When the Load method is executed, it only needs to meet the conditions of the environment variable filter out and added to the dictionary you can own configuration.

public class EnvironmentVariablesConfigurationProvider : ConfigurationProvider
{
    private readonly string _prefix;
    public EnvironmentVariablesConfigurationProvider(string prefix = null) =>  _prefix = prefix ?? string.Empty;
    public override void Load()
    {
        var dictionary = Environment.GetEnvironmentVariables()
            .Cast<DictionaryEntry>()
            .Where(it => it.Key.ToString().StartsWith( _prefix, StringComparison.OrdinalIgnoreCase))
            .ToDictionary(it => it.Key.ToString().Substring(_prefix.Length),   it => it.Value.ToString());
        Data = new Dictionary<string, string>( dictionary, StringComparer.OrdinalIgnoreCase);
    }
}

It is worth mentioning that, if after we specify a prefix for screening environment variables when creating EnvironmentVariablesConfigurationProvider object is added to the dictionary when configure themselves to meet the conditions of the environment variable, the name of this prefix configuration items will be removed . For example, after the prefix is set to "FOO_", the environment variable "FOO_BAR" is added to the configuration dictionary, configuration item name will become "BAR", this detail is also reflected in the Load method defined above.

When using EnvironmentVariablesConfigurationSource, we can call the Add method to register it to the specified IConfigurationBuilder object. Extension methods AddEnvironmentVariables In addition, EnvironmentVariablesConfigurationSource registration can also call directly IConfigurationBuilder interface to complete the following three overloaded.

public static class EnvironmentVariablesExtensions
{
    public  static IConfigurationBuilder AddEnvironmentVariables (   this IConfigurationBuilder configurationBuilder);
    public  static IConfigurationBuilder AddEnvironmentVariables (   this IConfigurationBuilder builder, Action <EnvironmentVariablesConfigurationSource> configureSource);
    public  static IConfigurationBuilder AddEnvironmentVariables (   this IConfigurationBuilder configurationBuilder, string prefix);
}

As usual we write a simple example to demonstrate how to use the environment variable as the source. As shown in the code segment below, we call the static method SetEnvironmentVariable the Environment is provided four environment variables having the same variable name prefix TEST_. We call the method AddEnvironmentVariables create an Environment
VariablesConfigurationSource to create objects and register their ConfigurationBuilder above, when the method is called we will set the environment variable name prefix "TEST_". We will eventually be binding ConfigurationBuilder build out IConfiguration subject to a Profile object.

public class Program
{
    public  static  void Main ()
    {
        Environment.SetEnvironmentVariable("TEST_GENDER", "Male");
        Environment.SetEnvironmentVariable("TEST_AGE", "18");
        Environment.SetEnvironmentVariable("TEST_CONTACTINFO:EMAILADDRESS", "[email protected]");
        Environment.SetEnvironmentVariable("TEST_CONTACTINFO:PHONENO", "123456789");

        var profile = new ConfigurationBuilder()
            .AddEnvironmentVariables("TEST_")
            .Build()
            .Get<Profile>();

        Debug.Assert(profile.Equals(new Profile(Gender.Male, 18, "[email protected]", "123456789")));
    }
}

Three, CommandLineConfigurationSource objects

In many cases, we will use the Self-Host a way to a boarding ASP.NET Core application hosting process, in which case we tend to use the command line to start boarding procedures. When starting a ASP.NET Core command-line application form, we hope to directly use the named line switches (Switch) to control the behavior of some applications, the command-line switches naturally became one of the commonly used configuration source. Configuration model supports this configuration for the source is achieved by CommandLineConfigurationSource, of the type defined in the NuGet package "Microsoft.Extensions.Configuration.CommandLine" in.

When a command to execute the command line options, command-line switches (including the name and value) is embodied as a simple string array, so that the fundamental purpose of naming CommandLineConfigurationSource switching from row to a string array configuration dictionary. To fully understand this transformation rules, we come to find out CommandLine
command line switches ConfigurationSource support the use of what kind of form to be specified. Through a simple example will be explained in several ways specified command-line switches. Suppose we have a command "exec" and by way of the following execution of a managed program (app).

exec app {options}

When we execute this command, specify multiple options through the appropriate command-line switch. In general, the form of command-line switches designated generally divided into two types, which I called " single parameter (Single the Argument )" and " two-parameter (Double the Arguments) ." In the form of so-called single parameter it is to use an equal sign ( "=") the name and value of command-line switches to using a parameter specified by the following method.

{name}={value}
{prefix}{name}={value}

For the second single parameter to specify the form of command-line switches, we can add a name prefix in front of the switch, the current support prefix " / ", " - " and " - " three. Following this format, we can use the following three ways architecture command-line switches to "x64". The following list is no reason why a "-" prefix, because this requires the use of the prefix "command line switch maps (Switch Mapping)", we'll do this later in this article alone.

exec app architecture=x64
exec app /architecture=x64
exec app --architecture=x64

In addition to the single parameter form, we can use two-argument form to specify the command-line switches, a so-called "two-parameter" is the use of two parameters define the name and value of the command-line switches, respectively. This particular format used is in the form "{prefix} {name} {value}", so the above command line switch architecture can be used also as a way to specify.

exec app /architecture x64
exec app –-architecture x64

Having a full name and abbreviation between command-line switches mapping relationship (the Mapping Switch) . Both the above-described command-line switches, for example, we can use the first letter "a" instead of "architecture". If - switch after the name as a prefix, whether single or dual parameter argument form, you must be mapped using the "." It is worth mentioning that, with a command line switch can have multiple maps, such as we can at the same time "architecture" mapped "arch". Assuming that "architecture" has these two maps, we can specify the CPU architecture in the following two ways.

exec app -a=x64
exec app -arch=x64
exec app -a x64
exec app -arch x64

In the understanding of the form specified command-line switches, then we say it CommandLineConfigurationSource type and CommandLineConfigurationProvider provided by it. Since the original command line parameters always embodied as a string of space-separated using such strings can be further converted into a set of strings, so CommandLineConfigurationSource configuration as a set of objects in the source string. As shown in the following code snippet, CommandLineConfigurationSource type having two Args and SwitchMappings properties former represents the original set of strings carrying the command line parameters, which are saved mapping relationship between the abbreviations and the full name of the command-line switches. CommandLineConfigurationSource Build-implemented method creates and returns an object based on CommandLineConfigurationProvider these two properties.

public  class CommandLineConfigurationSource: IConfigurationSource
{
    public IEnumerable<string> Args { get; set; }
    public IDictionary<string, string> SwitchMappings { get; set; }

    public IConfigurationProvider Build(IConfigurationBuilder builder) => new CommandLineConfigurationProvider( Args,SwitchMappings); 
}

CommandLineConfigurationProvider object has the following definition is still an abstract class ConfigurationProvider successor. The purpose CommandLineConfigurationProvider object is very clear, that is to reflect the original command-line parameters for the set of strings parsed, and adds the parsed configuration parameter name and value to the dictionary, all this is done in the Load method of rewriting .

public class CommandLineConfigurationProvider : ConfigurationProvider
{
    protected IEnumerable<string> Args { get; }
    public CommandLineConfigurationProvider(IEnumerable<string> args,  IDictionary<string, string> switchMappings = null);
    public override void Load();
}

When using command-line parameters based on a configuration source, we can create a CommandLineConfigurationSource and register it on ConfigurationBuilder. The following three expansion methods we can call IConfigurationBuilder interface AddCommandLine two steps into one.

public static class CommandLineConfigurationExtensions
{
    public static IConfigurationBuilder AddCommandLine(  this IConfigurationBuilder builder,  Action<CommandLineConfigurationSource> configureSource);
    public static IConfigurationBuilder AddCommandLine(  this IConfigurationBuilder configurationBuilder, string[] args);
    public static IConfigurationBuilder AddCommandLine(  this IConfigurationBuilder configurationBuilder, string[] args,  IDictionary<string, string> switchMappings);
}

In order to give readers and friends of CommandLineConfigurationSource / CommandLineConfigurationProvider Resolution Policy command-line arguments used to have a deep understanding, we demonstrate a simple example. As shown in the following code fragment, we create an object and call AddCommandLine ConfigurationBuilder method to register the configuration source for the command-line parameters, parameter args Main method directly as the original command-line arguments.

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var mapping = new Dictionary<string, string>
            {
                ["-a"]     = "architecture",
                ["-arch"]     = "architecture"
            };
            var configuration = new ConfigurationBuilder()
                .AddCommandLine(args, mapping)
                .Build();
            Console.WriteLine($"Architecture: {configuration["architecture"]}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}

When calling an extension method AddCommandLine registered CommandLineConfigurationSource, we specify a command line switch mapping table, it will be command-line switch "architecture" is mapped to "a" and "arch". Note that, when the switch is mapped by the dictionary definition of the command line as Key target name should add "-" prefix. Next we call the Build method of ConfigurationBuilder IConfiguration create objects, and extracting value "architecture" of configuration items and print them out. As shown below, we use the command line options and specify the start value "architecture" in different forms.

6-17

[ASP.NET Core 3 framework Secret] Configuration [1]: read configuration data [Part]
[ASP.NET Core 3 framework Secret] Configuration [2]: configuration data is read [next]
[ASP.NET Core 3 Secret frame] configuration [3]: overall design configuration model
[ASP.NET Core 3 framework Secret] configuration [4]: the bonding configuration object
[ASP.NET Core 3 framework Secret] configuration [5]: configuration data and data real-time synchronization source
[ASP.NET Core 3 framework Secret] configuration [6]: diverse configuration source [Part]
[ASP.NET Core 3 framework Secret] configuration [7]: diverse configuration source [medium-length]
[ASP.NET Core 3 framework Secret] configuration [8]: diverse configuration source [next]
[ASP.NET Core 3 framework Secret] configuration [9]: custom configuration source

Guess you like

Origin www.cnblogs.com/artech/p/inside-asp-net-core-05-06.html