亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在asp.net core中配置文件加載

發布時間:2021-05-23 19:44:27 來源:億速云 閱讀:187 作者:Leah 欄目:開發技術

怎么在asp.net core中配置文件加載?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

何時加載了默認的配置文件

在 Program.cs 文件中,查看以下代碼

 public class Program
 {
  public static void Main(string[] args)
  {
   CreateWebHostBuilder(args).Build().Run();
  }

  public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
   WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>();
 }

WebHost.CreateDefaultBuilder 位于程序集 Microsoft.AspNetCore.dll 內,當程序執行 WebHost.CreateDefaultBuilder(args) 的時候,在 CreateDefaultBuilder 方法內部加載了默認的配置文件

代碼如下

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
  {
   var builder = new WebHostBuilder();

   if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
   {
    builder.UseContentRoot(Directory.GetCurrentDirectory());
   }
   if (args != null)
   {
    builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
   }

   builder.UseKestrel((builderContext, options) =>
    {
     options.Configure(builderContext.Configuration.GetSection("Kestrel"));
    })
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
     var env = hostingContext.HostingEnvironment;

     config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
       .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

     if (env.IsDevelopment())
     {
      var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
      if (appAssembly != null)
      {
       config.AddUserSecrets(appAssembly, optional: true);
      }
     }

     config.AddEnvironmentVariables();

     if (args != null)
     {
      config.AddCommandLine(args);
     }
    })
    .ConfigureLogging((hostingContext, logging) =>
    {
     logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
     logging.AddConsole();
     logging.AddDebug();
     logging.AddEventSourceLogger();
    })
    .ConfigureServices((hostingContext, services) =>
    {
     // Fallback
     services.PostConfigure<HostFilteringOptions>(options =>
     {
      if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
      {
       // "AllowedHosts": "localhost;127.0.0.1;[::1]"
       var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
       // Fall back to "*" to disable.
       options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
      }
     });
     // Change notification
     services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
      new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));

     services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
    })
    .UseIIS()
    .UseIISIntegration()
    .UseDefaultServiceProvider((context, options) =>
    {
     options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
    });

   return builder;
  }

可以看到,CreateDefaultBuilder 內部還是使用了 IConfigurationBuilder 的實現,且寫死了默認配置文件的名字

public static IWebHostBuilder CreateDefaultBuilder(string[] args)
  {
   var builder = new WebHostBuilder();

   if (string.IsNullOrEmpty(builder.GetSetting(WebHostDefaults.ContentRootKey)))
   {
    builder.UseContentRoot(Directory.GetCurrentDirectory());
   }
   if (args != null)
   {
    builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build());
   }

   builder.UseKestrel((builderContext, options) =>
    {
     options.Configure(builderContext.Configuration.GetSection("Kestrel"));
    })
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
     var env = hostingContext.HostingEnvironment;

     config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
       .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

     if (env.IsDevelopment())
     {
      var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
      if (appAssembly != null)
      {
       config.AddUserSecrets(appAssembly, optional: true);
      }
     }

     config.AddEnvironmentVariables();

     if (args != null)
     {
      config.AddCommandLine(args);
     }
    })
    .ConfigureLogging((hostingContext, logging) =>
    {
     logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
     logging.AddConsole();
     logging.AddDebug();
     logging.AddEventSourceLogger();
    })
    .ConfigureServices((hostingContext, services) =>
    {
     // Fallback
     services.PostConfigure<HostFilteringOptions>(options =>
     {
      if (options.AllowedHosts == null || options.AllowedHosts.Count == 0)
      {
       // "AllowedHosts": "localhost;127.0.0.1;[::1]"
       var hosts = hostingContext.Configuration["AllowedHosts"]?.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
       // Fall back to "*" to disable.
       options.AllowedHosts = (hosts?.Length > 0 ? hosts : new[] { "*" });
      }
     });
     // Change notification
     services.AddSingleton<IOptionsChangeTokenSource<HostFilteringOptions>>(
      new ConfigurationChangeTokenSource<HostFilteringOptions>(hostingContext.Configuration));

     services.AddTransient<IStartupFilter, HostFilteringStartupFilter>();
    })
    .UseIIS()
    .UseIISIntegration()
    .UseDefaultServiceProvider((context, options) =>
    {
     options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
    });

   return builder;
  }

由于以上代碼,我們可以在應用程序根目錄下使用 appsettings.json appsettings.{env.EnvironmentName}.json 這種形式的默認配置文件名稱

并且,由于 Main 方法默認對配置文件進行了 Build 方法的調用操作

 public static void Main(string[] args)
  {
   CreateWebHostBuilder(args).Build().Run();
  }

我們可以在 Startup.cs 中使用注入的方式獲得默認的配置文件對象 IConfigurationRoot/IConfiguration,代碼片段

 public class Startup
 {
  public Startup(IConfiguration configuration)
  {
   Configuration = configuration;
  }

這是為什么呢,因為在 執行 Build 方法的時候,方法內部已經將默認配置文件對象加入了 ServiceCollection 中,代碼片段

 var services = new ServiceCollection();
 services.AddSingleton(_options);
 services.AddSingleton<IHostingEnvironment>(_hostingEnvironment);
 services.AddSingleton<Extensions.Hosting.IHostingEnvironment>(_hostingEnvironment);
 services.AddSingleton(_context);

 var builder = new ConfigurationBuilder()
    .SetBasePath(_hostingEnvironment.ContentRootPath)
    .AddConfiguration(_config);

 _configureAppConfigurationBuilder?.Invoke(_context, builder);

 var configuration = builder.Build();
 services.AddSingleton<IConfiguration>(configuration);
 _context.Configuration = configuration;

以上這段代碼非常熟悉,因為在 Startup.cs 文件中,我們也許會使用過 ServiceCollection 對象將業務系統的自定義對象加入服務上下文中,以方便后續接口注入使用。

AddJsonFile 方法的使用

通常情況下,我們都會使用默認的配置文件進行開發,或者使用 appsettings.{env.EnvironmentName}.json 的文件名稱方式來區分 開發/測試/產品 環境,根據環境變量加載不同的配置文件;可是這樣一來帶來了另外一個管理上的問題,產品環境的配置參數和開發環境

是不同的,如果使用環境變量的方式控制配置文件的加載,則可能導致密碼泄露等風險;誠然,可以手工在產品環境創建此文件,但是這樣一來,發布流程將會變得非常繁瑣,稍有錯漏文件便會被覆蓋。

我們推薦使用 AddJsonFile 加載產品環境配置,代碼如下

 public Startup(IConfiguration configuration, IHostingEnvironment env)
  {
   Configuration = AddCustomizedJsonFile(env).Build();

  }

  public ConfigurationBuilder AddCustomizedJsonFile(IHostingEnvironment env)
  {
   var build = new ConfigurationBuilder();
   build.SetBasePath(env.ContentRootPath).AddJsonFile("appsettings.json", true, true);
   if (env.IsProduction())
   {
    build.AddJsonFile(Path.Combine("/data/sites/config", "appsettings.json"), true, true);
   }
   return build;
  }

通過 AddCustomizedJsonFile 方法去創建一個 ConfigurationBuilder 對象,并覆蓋系統默認的 ConfigurationBuilder 對象,在方法內部,默認加載開發環境的配置文件,在產品模式下,額外加載目錄 /data/sites/config/appsettings.json 文件,

不同擔心配置文件沖突問題,相同鍵值的內容將由后加入的配置文件所覆蓋。

配置文件的變動

在調用 AddJsonFile 時,我們看到該方法共有 5 個重載的方法

其中一個方法包含了 4 個參數,代碼如下

 public static IConfigurationBuilder AddJsonFile(this IConfigurationBuilder builder, IFileProvider provider, string path, bool optional, bool reloadOnChange)
  {
   if (builder == null)
   {
    throw new ArgumentNullException(nameof(builder));
   }
   if (string.IsNullOrEmpty(path))
   {
    throw new ArgumentException(Resources.Error_InvalidFilePath, nameof(path));
   }

   return builder.AddJsonFile(s =>
   {
    s.FileProvider = provider;
    s.Path = path;
    s.Optional = optional;
    s.ReloadOnChange = reloadOnChange;
    s.ResolveFileProvider();
   });
  }

在此方法中,有一個參數 bool reloadOnChange,從參數描述可知,該值指示在文件變動的時候是否重新加載,默認值為:false;一般在手動加載配置文件,即調用 AddJsonFile 方法時,建議將該參數值設置為 true。

那么 .netcore 是如果通過該參數 reloadOnChange 是來監控文件變動,以及何時進行重新加載的操作呢,看下面代碼

  public IConfigurationRoot Build()
  {
   var providers = new List<IConfigurationProvider>();
   foreach (var source in Sources)
   {
    var provider = source.Build(this);
    providers.Add(provider);
   }
   return new ConfigurationRoot(providers);
  }

在我們執行 .Build 方法的時候,方法內部最后一行代碼給我們利用 AddJsonFile 方法的參數創建并返回了一個 ConfigurationRoot 對象

在 ConfigurationRoot 的構造方法中

  public ConfigurationRoot(IList<IConfigurationProvider> providers)
  {
   if (providers == null)
   {
    throw new ArgumentNullException(nameof(providers));
   }

   _providers = providers;
   foreach (var p in providers)
   {
    p.Load();
    ChangeToken.OnChange(() => p.GetReloadToken(), () => RaiseChanged());
   }
  }

我們看到,方法內部一次讀取了通過 AddJsonFile 方法加入的配置文件,并為每個配置文件單獨分配了一個監聽器 ChangeToken,并綁定當前文件讀取對象 IConfigurationProvider.GetReloadToken 方法到監聽器中

當文件產生變動的時候,監聽器會收到一個通知,同時,對該文件執行原子操作

 private void RaiseChanged()
  {
   var previousToken = Interlocked.Exchange(ref _changeToken, new ConfigurationReloadToken());
   previousToken.OnReload();
  }

由于 AddJsonFile 方法內部使用了 JsonConfigurationSource ,而 Build 的重載方法構造了一個 JsonConfigurationProvider 讀取對象,查看代碼

  public override IConfigurationProvider Build(IConfigurationBuilder builder)
  {
   EnsureDefaults(builder);
   return new JsonConfigurationProvider(this);
  }

在 JsonConfigurationProvider 繼承自 FileConfigurationProvider 類,該類位于程序集 Microsoft.Extensions.Configuration.Json.dll

在 FileConfigurationProvider 的構造方法中實現了監聽器重新加載配置文件的過程

  public FileConfigurationProvider(FileConfigurationSource source)
  {
   if (source == null)
   {
    throw new ArgumentNullException(nameof(source));
   }
   Source = source;

   if (Source.ReloadOnChange && Source.FileProvider != null)
   {
    ChangeToken.OnChange(
     () => Source.FileProvider.Watch(Source.Path),
     () => {
      Thread.Sleep(Source.ReloadDelay);
      Load(reload: true);
     });
   }
  }

值得注意的是,該監聽器不是在得到文件變動通知后第一時間去重新加載配置文件,方法內部可以看到,這里有一個 Thread.Sleep(Source.ReloadDelay) ,而 ReloadDelay 的默認值為:250ms,該屬性的描述為

  • 獲取或者設置重新加載將等待的毫秒數, 然后調用 "Load" 方法。 這有助于避免在完全寫入文件之前觸發重新加載。默認值為250

  • 讓人欣慰的是,我們可以自定義該值,如果業務對文件變動需求不是特別迫切,您可以將該值設置為一個很大的時間,通常情況下,我們不建議那么做

ASP.NET 是什么

ASP.NET 是開源,跨平臺,高性能,輕量級的 Web 應用構建框架,常用于通過 HTML、CSS、JavaScript 以及服務器腳本來構建網頁和網站。

關于怎么在asp.net core中配置文件加載問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永善县| 黎川县| 当雄县| 博乐市| 嫩江县| 沁水县| 西城区| 喜德县| 墨竹工卡县| 延安市| 天水市| 色达县| 大冶市| 互助| 延庆县| 镇原县| 滨海县| 台东县| 密山市| 吴川市| 大城县| 高唐县| 马龙县| 镇雄县| 阳朔县| 洛阳市| 盐亭县| 湛江市| 绥棱县| 佛学| 剑阁县| 马尔康县| 满洲里市| 肥东县| 新巴尔虎右旗| 隆昌县| 高要市| 台东县| 呼图壁县| 连南| 莱州市|