5.7、配置
5.7.1 获取并设置配置
var builder = new ConfigurationBuilder();
builder.AddInMemoryCollection();
var config = builder.Build();
config["somekey"] = "somevalue";
// do some other work
var setting = config["somekey"]; // also returns "somevalue"
5.7.2 使用内置源
如果一个字符串存在于多个配置文件中。最后一个配置源将被使用。ASP.NET团队建议最后指定环境变量,以便本地环境可以覆盖部署中设置的任何配置文件。
环境指定的配置文件。
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); if (env.IsDevelopment()) { // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=builder.AddUserSecrets(); } builder.AddEnvironmentVariables(); Configuration = builder.Build(); }在开发环境中,上面代码将查找名为appsettings.Development.json的文件并使用它的值。您不应该在configuration provider或纯文本中存储密码或其他敏感数据。 您也不应在开发或测试环境中使用生产秘密。相反,这样的秘密应该在项目之外指定。
+++ 指定默认值
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Configuration; namespace ConfigConsole { public static class Program { public static void Main(string[] args) { var builder = new ConfigurationBuilder(); Console.WriteLine("Initial Config Sources: " + builder.Sources.Count()); builder.AddInMemoryCollection(new Dictionary<string, string> { { "username", "Guest" } }); Console.WriteLine("Added Memory Source. Sources: " + builder.Sources.Count()); builder.AddCommandLine(args); Console.WriteLine("Added Command Line Source. Sources: " + builder.Sources.Count()); var config = builder.Build(); string username = config["username"]; Console.WriteLine($"Hello, {username}!"); } } }
5.7.3 使用Options对象和configuration对象
IOptions<TOptions>public class MyOptions { public string Option1 { get; set; } public int Option2 { get; set; } }public class HomeController : Controller { private readonly IOptions<MyOptions> _optionsAccessor; public HomeController(IOptions<MyOptions> optionsAccessor) { _optionsAccessor = optionsAccessor; } // GET: /<controller>/ public IActionResult Index() => View(_optionsAccessor.Value); }public void ConfigureServices(IServiceCollection services) { // Setup options with DI services.AddOptions(); }使用delegate或者是绑定options到configuration
public void ConfigureServices(IServiceCollection services) { // Setup options with DI services.AddOptions(); // Configure MyOptions using config by installing Microsoft.Extensions.Options.ConfigurationExtensions services.Configure<MyOptions>(Configuration); // Configure MyOptions using code services.Configure<MyOptions>(myOptions => { myOptions.Option1 = "value1_from_action"; }); // Configure MySubOptions using a sub-section of the appsettings.json file services.Configure<MySubOptions>(Configuration.GetSection("subsection")); // Add framework services. services.AddMvc(); }每次调用
Configure <TOptions>会将IConfigureOptions <TOptions>服务添加到IOptions <TOptions>服务使用的服务容器中,以提供configured options到应用程序或框架。 如果要使用对象来配置Option,那么对象必须从服务容器中获取(例如,从数据库中读取设置)使用AddSingleton<IConfigureOptions<TOptions>>扩展方法注册自定义IConfigureOptions<TOptions>服务。
5.7.4 编写自定义providers
举例:Entity Framework Settings
public class ConfigurationValue { public string Id { get; set; } public string Value { get; set; } }public class ConfigurationContext : DbContext { public ConfigurationContext(DbContextOptions options) : base(options) { } public DbSet<ConfigurationValue> Values { get; set; } }using System; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace CustomConfigurationProvider { public class EntityFrameworkConfigurationSource : IConfigurationSource { private readonly Action<DbContextOptionsBuilder> _optionsAction; public EntityFrameworkConfigurationSource(Action<DbContextOptionsBuilder> optionsAction) { _optionsAction = optionsAction; } public IConfigurationProvider Build(IConfigurationBuilder builder) { return new EntityFrameworkConfigurationProvider(_optionsAction); } } }using System; using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace CustomConfigurationProvider { public class EntityFrameworkConfigurationProvider : ConfigurationProvider { public EntityFrameworkConfigurationProvider(Action<DbContextOptionsBuilder> optionsAction) { OptionsAction = optionsAction; } Action<DbContextOptionsBuilder> OptionsAction { get; } public override void Load() { var builder = new DbContextOptionsBuilder<ConfigurationContext>(); OptionsAction(builder); using (var dbContext = new ConfigurationContext(builder.Options)) { dbContext.Database.EnsureCreated(); Data = !dbContext.Values.Any() ? CreateAndSaveDefaultValues(dbContext) : dbContext.Values.ToDictionary(c => c.Id, c => c.Value); } } private static IDictionary<string, string> CreateAndSaveDefaultValues( ConfigurationContext dbContext) { var configValues = new Dictionary<string, string> { { "key1", "value_from_ef_1" }, { "key2", "value_from_ef_2" } }; dbContext.Values.AddRange(configValues .Select(kvp => new ConfigurationValue { Id = kvp.Key, Value = kvp.Value }) .ToArray()); dbContext.SaveChanges(); return configValues; } } }AddEntityFrameworkConfiguration
using System; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace CustomConfigurationProvider { public static class EntityFrameworkExtensions { public static IConfigurationBuilder AddEntityFrameworkConfig( this IConfigurationBuilder builder, Action<DbContextOptionsBuilder> setup) { return builder.Add(new EntityFrameworkConfigurationSource(setup)); } } }using System; using System.IO; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; namespace CustomConfigurationProvider { public static class Program { public static void Main() { // work with with a builder using multiple calls var builder = new ConfigurationBuilder(); builder.SetBasePath(Directory.GetCurrentDirectory()); builder.AddJsonFile("appsettings.json"); var connectionStringConfig = builder.Build(); // chain calls together as a fluent API var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddEntityFrameworkConfig(options => options.UseSqlServer(connectionStringConfig.GetConnectionString("DefaultConnection"))).Build(); Console.WriteLine("key1={0}", config["key1"]); Console.WriteLine("key2={0}", config["key2"]); Console.WriteLine("key3={0}", config["key3"]); } } }5.7.5 小结
ASP.NET Core提供了一个非常灵活的配置模型,支持多种不同的基于文件的方式,同时还包括命令行,内存和环境变量等。 它与选项模型无缝工作,让您可以将强类型设置注入到您的应用程序或框架中。 您可以创建自己的自定义configuration providers,它可以与内置的providers一起工作或替换内部的providers,具有极大的灵活性。