AI智能
改变未来

ASP.NET Core 学习笔记 第四篇 ASP.NET Core 中的配置


前言

最近有点忙,学习有点懈怠(惭愧),抽时间学习把这篇博客写完,希望理解。相信自己能坚持下去,把这个系列写完。好啦,开搞。说道配置文件,基本大多数软件为了扩展性、灵活性都会涉及到配置文件,比如之前常见的app.config和web.config。然后再说.NET Core,很多都发生了变化。总体的来说技术在进步,新的方式更加轻量级,具有更好的扩展性,数据源更加多样性。

ASP.NET Core 应用可用的配置提供程序

提供程序 一下对象提供配置
Azure Key Vault 配置提供程序 Azure Key Vault
Azure 应用配置提供程序 Azure 应用程序配置
命令行配置提供程序 命令行参数
自定义配置提供程序 自定义源
环境变量配置提供程序 环境变量
文件配置提供程序 INI、JSON 和 XML 文件
Key-per-file 配置提供程序 目录文件
内存配置提供程序 内存中集合
用户机密 用户配置文件目录中的文件

配置提供程序的典型顺序为:
1.appsettings.json
2.appsettings.Environment.json
3.用户机密
4.使用环境变量配置提供程序通过环境变量提供。
5.使用命令行配置提供程序通过命令行参数提供。
注意: 通常的做法是将命令行配置提供程序添加到一系列提供程序的末尾,使命令行参数能够替代由其他提供程序设置的配置。

配置模型三要素

.NET Core的配置系统由三个核心对象构成,分别是IConfiguration、IConfigurationBuilder、IConfigurationSource。

  • IConfiguration:读取出来的配置信息最终会转换成一个IConfiguration对象供应用程序使用。
  • IConfigurationBuilder:IConfigurationBuilder是IConfiguration对象的构建者。
  • IConfigurationSource:则代表配置数据最原始的来源。

文件配置

读取INI文件配置

首先创建一个ASP .NET Core Web API项目,在主目录下添加MyIniConfig.ini文件。

ID=1Title=\"INIConfig title\"Name=\"INIConfig name\"[Logging:LogLevel]Default=Information

在Program类中读取配置文件

public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) =>{config.Sources.Clear();var env = hostingContext.HostingEnvironment;config.AddIniFile(\"MyIniConfig.ini\", optional: true, reloadOnChange: true);              config.AddEnvironmentVariables();if (args != null){config.AddCommandLine(args);}}).ConfigureWebHostDefaults(webBuilder =>{webBad8uilder.UseStartup<Startup>();});}

新建一个名为SettingsController的控制器,读取配置文件。

[Route(\"api/[controller]/[action]\")][ApiController]public class SettingsController : ControllerBase{private readonly IConfiguration Configuration;public SettingsController(IConfiguration configuration){Configuration = configuration;}public ContentResult INISetting(){int id = Configuration.GetValue<int>(\"ID\");var title = Configuration[\"Title\"];var defaultLogLevel = Configuration[\"Logging:LogLevel:Default\"];return Content($\"ID:{id}\\n\" +$\"Title:{title}\\n\"+$\"Default Log Level: {defaultLogLevel}\");}}

利用PostMan可以看到已经读取到刚刚设置的INI文件。

读取Json配置文件。

新建ASP.NET Core Web API项目,在主目录下添加MyJsonConfig.json文件。

{\"ID\": \"1\",\"Title\": \"My JsonConfig\",\"Logging\": {\"LogLevel\": {\"Default\": \"Information\"}}}

在Program类中读取配置文件

public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) =>{config.Sources.Clear();var env = hostingContext.HostingEnvironment;config.AddJsonFile(\"MyJsonConfig.json\", optional: true, reloadOnChange: true);config.AddEnvironmentVariables();if (args != null){config.AddCommandLine(args);}}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}

新建一个名为SettingsController的控制器,读取配置文件。

[Route(\"api/[controller]/[action]\")][ApiController]public class SettingsController : ControllerBase{private readonly IConfiguration Configuration;public SettingsController(IConfiguration configuration){Configuration = configuration;}public ContentResult JsonSetting()2b58{int id = Configuration.GetValue<int>(\"ID\");var title = Configuration[\"Title\"];var defaultLogLevel = Configuration[\"Logging:LogLevel:Default\"];return Content($\"ID:{id}\\n\" + $\"Title:{title}\\n\" +$\"Default Log Level: {defaultLogLevel}\");}}

利用PostMan可以看到已经读取到刚刚设置的Json文件。

读取XML文件

新建ASP.NET Core Web API项目,在主目录下添加MyXMLConfig.xml文件。

<?xml version=\"1.0\" encoding=\"utf-8\" ?><configuration><ID>1</ID><Title>MyXMLConfig Title</Title><Name>MyXMLConfig Name</Name><Logging><LogLevel><Default>Information</Default></LogLevel></Logging></configuration>

在Program类中读取配置文件

public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) =>{config.Sources.Clear();var env = hostingContext.HostingEnvironment;config.AddXmlFile(\"MyXMLConfig.xml\", optional: true, reloadOnChange: true);config.AddEnvironmentVariables();if (args != null){config.AddCommandLine(args);}}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}

新建一个名为SettingsController的控制器,读取配置文件。

[Route(\"api/[controller]/[action]\")][ApiController]public class SettingsController : ControllerBase{private readonly IConfiguration Configuration;public SettingsController(IConfiguration configuration){Configuration = configuration;}public ContentResult XmlSetting(){int id = Configuration.GetValue<int>(\"ID\");var title = Configuration[\"Title\"];var defaultLogLevel = Configuration[\"Logging:LogLevel:Default\"];return Content($\"ID:{id}\\n\" + $\"Title:{title}\\n\" +$\"Default Log Level: {defaultLogLevel}\");}}

利用PostMan可以看到已经读取到XML文件的配置。

读取配置项的方法

说几个在读取配置项中比较常用的方法,大家可以根据上面例子,自己试一下,这里就不详细讲解了。

GetValue

ConfigurationBinder.GetValue 从配置中提取一个具有指定键的值,并将它转换为指定的类型。在上面的中

int id = Configuration.GetValue(\"ID\");

就是利用这个方法获取指定类型。

GetSection

IConfiguration.GetSection 会返回具有指定子节键的配置子节。

GetChildren

IConfiguration.GetChildren 方法获取直接后代配置子节。

Exists

ConfigurationExtensions.Exists(IConfigurationSection)确定该部分是否具有 Value 或子级。

将配置绑定到对象

新建ASP.NET Core Web API项目,在主目录下添加MyArray.json文件。

{\"array\": {\"entries\": {\"0\": \"value0\",\"1\": \"value1\",\"2\": \"value2\",\"3\": \"value3\"}}}

创建一个model。

public class Model{public string[] Entries { get; set; }}

在Program类中读取配置文件

public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) =>{config.Sources.Clear();var env = hostingContext.HostingEnvironment;config.AddJsonFile(\"MyArray.json\",optional: true,reloadOnChange: true);config.AddEnvironmentVariables();if (args != null){config.AddCommandLine(args);}}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}

新建一个名为SettingsController的控制器,读取配置文件。

[Route(\"api/[controller]/[action]\")][ApiController]public class SettingsController : ControllerBase{private readonly IConfiguration Configuration;public SettingsController(IConfiguration configuration){Configuration = configuration;}public ContentResult ToModel(){array = Configuration.GetSection(\"array\").Get<Model>();string modelStr = null;for (int j = 0; j < array.Entries.Length; j++){modelStr += $\"Index: {j}  Value:  {array.Entries[j]} \\n\";}return Content(modelStr);}}

利用PostMan可以看到已经读取到绑定到Model的配置。

自定义配置

如果上面的方式还不能满足项目要求的话,还可以从数据库中读取配置信息。接下来我们通过实体框架(EF)读取数据库中配置信息(埋个伏笔,后续做个相关教程)。便于操作,这次使用内存数据库做配置源。
首先做一个创建一个实体。

public class EFModel{public int ID { get; set; }public string Name { get; set; }public string Value { get; set; }}

添加 EFConfigContext 以存储和访问配置的值。

public class EFConfigContext:DbContext{public EFConfigContext(DbContextOptions options) : base(options){}public DbSet<EFModel> Values { get; set; }}

创建用于实现 IConfigurationSource 的类。

public class EFConfigurationSource : IConfigurationSource{private readonly Action<DbContextOptionsBuilder> _optionsAction;public EFConfigurationSource(Action<DbContextOptionsBuilder> optionsAction){_optionsAction = optionsAction;}public IConfigurationProvider Build(IConfigurationBuilder builder){return new EFConfigurationProvider(_optionsAction);}}

通过从 ConfigurationProvider 继承来创建自定义配置提供程序。 当数据库为空时,配置提供程序将对其进行初始化。

public class EFConfigurationProvider:ConfigurationProvider{Action<DbContextOptionsBuilder> OptionsAction { get; }public EFConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction){OptionsAction = optionsAction;}public override void Load(){var builder = new DbContextOptionsBuilder<EFConfigContext>();OptionsAction(builder);using (var dbContext =new EFConfigContext(builder.Options)){dbContext.Database.EnsureCreated();Data =!dbContext.Values.Any()?CreateAndSaveValues(dbContext) : dbContext.Values.ToDictionary(c => c.Name, c => c.Value);}}private static IDictionary<string, string> CreateAndSaveValues(EFConfigContext dbContext){var configValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase){{\"name1\",\"value1\" },{\"name2\",\"value2\" },{\"name3\",\"value3\" }};dbContext.Values.AddRange(configValues.Select(v => new EFModel{Name = v.Key,Value = v.Value}).ToArray());dbContext.SaveChanges();return configValues;}}

使用 AddEFConfiguration 扩展方法将配置源添加到 ConfigurationBuilder。

public static class EFExtensions{public static IConfigurationBuilder AddEFConfiguration(this IConfigurationBuilder builder,Action<DbContextOptionsBuilder> optionsAction){return builder.Add(new EFConfigurationSource(optionsAction));}}

在 Program.cs 中使用自定义的 EFConfigurationProvider:

public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureAppConfiguration((hostingContext, config) =>{config.Sources.Clear();var env = hostingContext.HostingEnvironment;config.AddEFConfiguration(options => options.UseInMemoryDatabase(\"InMemoryDb\"));config.AddEnvironmentVariables();if (args != null){config.AddCommandLine(args);}}).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();});}

在Startup中通过依赖注入添加据库上下文服务,向控制器提供服务。

public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }public void ConfigureServices(IServiceCollection services){services.AddDbContext<EFConfigContext>(opt => opt.UseInMemoryData2088base(\"InMemoryDb\"));services.AddControllers();}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoints =>{endpoints.MapControllers();});}}

在控制器中注入服务,读取内存数据库中的数据。

[Route(\"api/[controller]/[action]\")][ApiController]public class SettingsController : ControllerBase{private readonly EFConfigContext _efDbContext;public SettingsController( EFConfigContext efDbContext){_efDbContext = efDbContext;}public ActionResult<IEnumerable<EFModel>> EFSetting(){List<EFModel> list = _efDbContext.Values.ToList();return list;}}

利用PostMan可以看到已经读取到我们自定义的配置源。

加一张整体的项目结构,方便大家理解。

最近疫情有些反复,出门做好个人防护,玩耍时别忘记学习。最后祝大家周末愉快!

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » ASP.NET Core 学习笔记 第四篇 ASP.NET Core 中的配置