第18章 配置文件的自动新建及其覆盖性写入
1 准备工作
1.1 重构Data.EFCoreContext拷贝构造方法为:
#region 拷贝构造方法
///<param name="options">配置参数实例,通过配置参数实例,调用基类的拷贝构造方法以实现“Microsoft.EntityFrameworkCore.SqlServer”中间件与(SQL Server)数据库软件中指定数据库的连接。</param>
/// <summary>
/// 【拷贝构造方法】
/// <remarks>
/// 摘要:
/// 基类构造方法通过该类构造方法中的参数实例,实例化了“Microsoft.EntityFrameworkCore.SqlServer”中间件,
/// 以实现“Microsoft.EntityFrameworkCore.SqlServer”中间件与指定数据库(SQL Server)数据库软件中的指定数据库的连接,
/// 最终达到实体与相应表之间通过“Microsoft.EntityFrameworkCore.SqlServer”中间件进行CURD的交互操作的目的(功能)。
/// </remarks>
/// </summary>
public EFCoreContext(DbContextOptions<EFCoreContext> options) : base(options)
{
//如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则通过下1行语句结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表和字段。
//Database.EnsureCreated();
/*
如果(SQL Server)数据库软件中没有指定的数据库, 当通过Code First模式时,在第1次生成数据库时,则也通过下行执行迁移和更新命令行的结合数据库连接字符串,在(SQL Server)数据库软件中生成指定的数据库数据库、表和字段。
Add-Migration Initialize(Initialize:自动生成的迁移类名,这里特指:20220803125612_Initialize.cs):
Update-Database Initialize(通过自动生成的迁移类中的定义,自动在指定的数据库软件中生成指定的数据库、表、字段和约束规则)
*/
}
#endregion
1.2 先删除启用项中的"appsettings.json"文件
2 配置文件的自动新建及其覆盖性写入
2.1 Data.Configuration.DataSettingsManager
using Core.Configuration;
using Core.Infrastructure;
namespace Data.Configuration
{
/// <summary>
/// 【数据库设定管理器--类】
/// <remarks>
/// 摘要:
/// 通过该类方法成员把数据库连接配置类的1个指定实例以键/值对的形式存储到单例实例的变量和属性字典成员实例中,并把这些数据覆盖性的持久化存储到"appsettings.json"文件。。
/// </remarks>
/// </summary>
public class DataSettingsManager
{
#region 变量--私有/保护
/// <summary>
/// 【已经连接数据库软件?】
/// <remarks>
/// 摘要:
/// 设置1个值false(不存在)/true(存在),该值指示数据库连接配置实例中是否存在数据库连接字符串,即数据库连接字符串的值不能为:null。
/// </remarks>
/// </summary>
private static bool? _databaseIsInstalled;
#endregion
#region 方法
/// <param name="reload">指示是否需要把数据库连接配置类的1个1个新的指定实例,重新以键/值对的形式存储到单例实例的变量和属性字典成员实例中,默认值:false,即不需要。</param>
/// <summary>
/// 【获取SQL命令超时】
/// <remarks>
/// 摘要:
/// 把数据库连接配置类的1个新的指定实例,重新以键/值对的形式存储到单例实例的变量和属性字典成员实例中
/// </remarks>
/// <returns>
/// 返回:
/// 数据库连接配置类的1个新的指定实例。
/// </returns>
/// </summary>
public static DataConfig LoadSettings(bool reload = false)
{
//如果单例实例的字典成员实例中的数据库配置类的实例为:null,则直接退出当前方法。
if (!reload && Singleton<DataConfig>.Instance is not null)
return Singleton<DataConfig>.Instance;
//从单例实例的字典成员实例中获取数据库连接相关数据。
Singleton<DataConfig>.Instance = Singleton<AppSettings>.Instance.Get<DataConfig>();
return Singleton<DataConfig>.Instance;
}
/// <param name="dataSettings">数据库连接配置类的1个指定实例。</param>
/// <param name="fileProvider">自定义文件提供程序接口的1个指定实例。</param>
/// <summary>
/// 【保存设置】
/// <remarks>
/// 摘要:
/// 把数据库连接配置类的1个指定实例以键/值对的形式存储到单例实例的变量和属性字典成员实例中,并把这些数据覆盖性的持久化存储到"appsettings.json"文件。
/// </remarks>
/// </summary>
public static void SaveSettings(DataConfig dataSettings, INopFileProvider fileProvider)
{
//数据库连接配置类的1个指定实例以键/值对的形式存储到单例实例的变量和属性字典成员实例中,并把这些数据覆盖性的持久化存储到"appsettings.json"文件。
AppSettingsHelper.SaveAppSettings(new List<IConfig> { dataSettings }, fileProvider);
//把当前程序中所有继承了“IConfig”接口的具体实现类的实例,存储到单例实例的字典成员实例中。
LoadSettings(reload: true);
}
/// <summary>
/// 【已经连接数据库软件?】
/// <remarks>
/// 摘要:
/// 获取1个值false(不存在)/true(存在),该值指示数据库连接配置实例中是否存在数据库连接字符串,即数据库连接字符串的值不能为:null。
/// </remarks>
/// <returns>
/// 返回:
/// 1个值false(不存在)/true(存在)。
/// </returns>
/// </summary>
public static bool IsDatabaseInstalled()
{
_databaseIsInstalled ??= !string.IsNullOrEmpty(LoadSettings()?.ConnectionString);
return _databaseIsInstalled.Value;
}
/// <summary>
/// 【获取SQL命令超时】
/// <remarks>
/// 摘要:
/// 获取1个指定数据库的在终止执行SQL命令的尝试并生成错误之前的等待时间值(以秒为单位),如果在当前程序执行SQL命令的时间超过该属性实例的设置值,
/// 则终止程序对指定SQL命令的执行,返回值:0对应默认值为:null,即未设置为:0,如果数据库软件中的指定数据库在执行行SQL命令时产生错误时,不必须等待直接输出错误/异常信息;
/// 返回值:0对应:为无限等待,即如果数据库软件中的指定数据库在执行行SQL命令时产生错误时,会一直等待下去,而不会输出错误/异常信息。
/// </remarks>
/// <returns>
/// 返回:
/// 1个指定数据库的在终止执行SQL命令的尝试并生成错误之前的等待时间值(以秒为单位)。
/// </returns>
/// </summary>
public static int GetSqlCommandTimeout()
{
return LoadSettings()?.SQLCommandTimeout ?? -1;
}
#endregion
}
}
3.2 重构WebApi.Controllers. MulDatabaseTestController
using Core.Domain.Users;
using Core.Infrastructure;
using Data;
using Data.Configuration;
using Data.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.FileProviders;
namespace WebApi.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class MulDatabaseTestController : ControllerBase
{
#region 拷贝构造方法与变量
private readonly EFCoreContext _context;
private readonly INopFileProvider _fileProvider;
public MulDatabaseTestController(EFCoreContext context, INopFileProvider fileProvider)
{
_context = context;
_fileProvider = fileProvider;
}
#endregion
#region 方法
/// <summary>
/// 【获取角色列表--需权限】
/// </summary>
/// <remarks>
/// 摘要:
/// 从角色表中获取角色实体的所有实例,并把这些实例存储到列表实例中。
/// </remarks>
/// <returns>
/// 返回:
/// 列表实例,该实例存储着角色实体的所有实例。
/// </returns>
[HttpGet]
public async Task<List<Role>> GetRoleListAsync()
{
DataSettingsManager.SaveSettings(new DataConfig
{
DataProvider = DataProviderType.SqlServer,
ConnectionString = "Data Source=.;Initial Catalog=ShopDemo;Integrated Security=False;Persist Security Info=False;User ID=zz;Password=zz;MultipleActiveResultSets=true;Trust Server Certificate=True"
}, _fileProvider);
//通过“Microsoft.EntityFrameworkCore”实例以Code-First方式删除和创建数据库。
//_context.Database.EnsureDeleted();
//_context.Database.EnsureCreated();
//return await _context.GetDbSet<Role>().ToListAsync();
return null;
}
#endregion
}
}
3.3 重构Program.cs文件
var builder = WebApplication.CreateBuilder(args);
//如果启动项中不存在“appsettings.json”文件,则通过.Net(Core)的内置方法自动新建“appsettings.json”文件。
builder.Configuration.AddJsonFile("appsettings.json", true, true);
//把当前程序中所有继承了“IConfig”接口的具体实现类的实例,依赖注入到.Net(Core)内置依赖注入容器实例中,如果需要并把这些数据持久化存储到"appsettings.json"文件。
builder.Services.ConfigureApplicationSettings(builder);
按F5执行程序后,会在程序的启动项中自动生成"appsettings.json"文件;并执行GetRoleListAsync方法会把数据库连接相关的数据覆盖性的持久化到"appsettings.json"文件中。
对以上功能更为具体实现和注释见230116_012shopDemo(配置文件的自动新建及其覆盖性写入)。