[ASP.NET Core 3 framework Secret] Configuration [9]: custom configuration source

We face the first model in the default configuration IConfigurationSource implementation provided the type of in-depth detailed introduction, if they still can not meet the needs of the project, we can also achieve IConfigurationSource types to support our hope that through custom configuration source. Way to configure the persistent data, the configuration is stored in the database should be a common way. Next we'll create an implementation type for IConfigurationSource database, it uses the Entity Framework Core complete access to the database.

We named this custom ConfigurationSource DbConfigurationSource. In formally introduced it prior to implementation, we take a look at its use in the project. We will configure a data table stored in the SQL Server database, and using Entity Framework Core to read it. We will configure the connection string as defined in the JSON file named "appSettings.json" in.

{
  "connectionStrings": {
    "DefaultDb":  "Server = ... ; Database=...; Uid = ...; Pwd = ..."
  }
}

In the demonstration program below, we first create a ConfigurationBuilder objects, and on it a pointer to the object is registered JsonConfigurationSource connectionString.json file. Register for DbConfigurationSource object reflected in the extension method AddDatabase on this method has two parameters, representing the name and the initial configuration data connection string. The former is connected string name connectionString.json DefaultDB provided, which is a dictionary object, which provides exactly the original configuration may constitute a Profile object. After you create the corresponding objects IConfiguration use ConfigurationBuilde objects, we read the configuration to bind to a Profile object.

public class Program
{
    static void Main()
    {
        var initialSettings = new Dictionary<string, string>
        {
            ["Gender"] = "Male",
            ["Age"] = "18",
            ["ContactInfo:EmailAddress"] = "[email protected]",
            ["ContactInfo:PhoneNo"] = "123456789"
        };

        var profile = new ConfigurationBuilder()
            .AddJsonFile("appSettings.json")
            .AddDatabase("DefaultDb", initialSettings)
            .Build()
            .Get<Profile>();

        Debug.Assert(profile.Gender == Gender.Male);
        Debug.Assert(profile.Age == 18);
        Debug.Assert(profile.ContactInfo.EmailAddress == "[email protected]");
        Debug.Assert(profile.ContactInfo.PhoneNo == "123456789");
    }
}

As shown in the above code snippet for the application DbConfigurationSource only reflected in the AddDatabase extension methods defined for IConfigurationBuilder our target, so it is very convenient to use, this method has a kind of behind the extended logic to achieve it? Entity Framework Core DbConfigurationSource using Code First and to data manipulation manner, ApplicationSetting shown below shows the basic configuration item POCO type, we will configure Key items stored in lowercase. Another is the corresponding ApplicationSettingsContext DbContext type.

[Table("ApplicationSettings")]
public class ApplicationSetting
{
    private string key;

    [Key]
    public string Key
    {
        get { return key; }
        set { key = value.ToLowerInvariant(); }
    }

    [Required]
    [MaxLength(512)]
    public string Value { get; set; }

    public ApplicationSetting()
    { }

    public ApplicationSetting(string key, string value)
    {
        Key = key;
        Value = value;
    }
}

public class ApplicationSettingsContext : DbContext
{
    public ApplicationSettingsContext(DbContextOptions options) : base(options)
    { }

    public DbSet<ApplicationSetting> Settings { get; set; }
}

DbConfigurationSource type is shown belowDefinition, its constructor has two parameters, the first parameter of type Action <DbContextOptionsBuilder>, we use the delegate object to create DbContextOptions DbContext used to set, another alternative to specify a number of parameters to be automatically initialization of configuration items. DbConfigurationSource use in the method Build rewrite of these two objects to create a DbConfigurationProvider object.

public class DbConfigurationSource : IConfigurationSource
{
    private Action<DbContextOptionsBuilder> _setup;
    private IDictionary<string, string> _initialSettings;

    public DbConfigurationSource(Action<DbContextOptionsBuilder> setup, IDictionary<string, string> initialSettings = null)
    {
        _setup = setup;
        _initialSettings     = initialSettings;
    }
    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new DbConfigurationProvider(_setup, _initialSettings);
    }
}

DbConfigurationProvider derived from the abstract class ConfigurationProvider. In the Load method of rewriting, it creates an object according ApplicationSettingsContext Action <DbContextOptionsBuilder> offer, and use it to read from the database and configuration data into a dictionary and assigned to the representative configuration dictionary Data property. If there is no data in the data table, the method also initializes the use of the provided object configuration DbContext added to the database.

public class DbConfigurationProvider: ConfigurationProvider
{
    private readonly IDictionary<string, string> _initialSettings;
    private readonly Action<DbContextOptionsBuilder> _setup;

    public DbConfigurationProvider(Action<DbContextOptionsBuilder> setup,  IDictionary<string, string> initialSettings)
    {
        _setup  = setup;
        _initialSettings     = initialSettings?? new Dictionary<string, string>() ;
    }

    public override void Load()
    {
        var builder =  new DbContextOptionsBuilder<ApplicationSettingsContext>();
        _setup(builder);
        using (ApplicationSettingsContext dbContext =  new ApplicationSettingsContext(builder.Options))
        {
            dbContext.Database.EnsureCreated();
            Data = dbContext.Settings.Any()
                ? dbContext.Settings.ToDictionary(it => it.Key, it => it.Value,  StringComparer.OrdinalIgnoreCase)
                : Initialize(dbContext);
        }
    }

    private IDictionary<string, string> Initialize( ApplicationSettingsContext dbContext)
    {
        foreach (var item in _initialSettings)
        {
            dbContext.Settings.Add(new ApplicationSetting(item.Key, item.Value));
        }
        return _initialSettings.ToDictionary(it => it.Key, it => it.Value,  StringComparer.OrdinalIgnoreCase);
    }
}

Examples DbConfigurationSource presentation to register objects extension method AddDatabase have the following definitions. This method first calls IConfigurationBuilder objects Build IConfiguration method for creating an object and call the object [A5] extension method GetConnectionString complete connection string obtained according to the specified connection name string. Next we call the constructor creates a DbConfigurationSource object and register to ConfigurationBuilder objects on. DbConfigurationSource specify when you create an object Action <DbContextOptionsBuilder> will complete the setting for the connection string.

public static class DbConfigurationExtensions
{
    public static IConfigurationBuilder AddDatabase(  this IConfigurationBuilder builder, string connectionStringName,  IDictionary<string, string> initialSettings = null)
    {
        var connectionString = builder.Build() .GetConnectionString(connectionStringName);
        var source = new DbConfigurationSource( optionsBuilder => optionsBuilder.UseSqlServer(connectionString), initialSettings);
        builder.Add(source);
        return builder;
    }
}

[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-09.html