Ne yapmaya çalışıyorum: Azure Uygulama Yapılandırması'nda bir sentinel anahtarı olan bir .net çekirdeği 2.1 mvc web uygulaması ile Azure Uygulama Yapılandırması'nı, Azure'daki anahtarları ve anahtarların hiçbirini değiştirememek amacıyla kurmaya çalışıyorum sentinel değeri değişene kadar uygulamalarımda güncellenecek. Teorik olarak, bu, hot swap yapılandırmalarını güvenli bir şekilde kullanmama izin vermelidir.
Benim sorunum: Bunu yaptığımda, IWebHostBuilder üzerinde sentinel izlemek için kullanılabilir bir WatchAndReloadAll () yöntemi yoktur ve alternatif Refresh () yöntemleri, durum olarak yapılandırmayı yenilemek gibi görünmüyor.
Arka Plan Bilgileri ve ne denedim: Geçen hafta VS Live - San Diego'ya katıldım ve Azure Uygulama Yapılandırması ile ilgili bir demo izledim. Ben implimenting zaman yapılandırma değerlerini yenilemek için uygulamayı almak için çalışırken bazı sorunlar vardı, bu yüzden de nasıl bunu açıklayan bu demo referans . İlgili bölüm yaklaşık 10 dakika uzaklıktadır. Ancak, bu yöntem IWebHostBuilder'da mevcut görünmemektedir.
Belgeleme atıfta bulunuyorum: Resmi belgelerde bu yönteme ilişkin bir referans yoktur bkz. Doc quickstart .net core ve doc dynamic configuration .net core
Benim Çevre: Net çekirdek 2.1 nokta Kullanılması 2.0.0-önizleme 010060003-1250 Microsoft.Azure.AppConfiguration.AspNetCore için en son önizleme Nuget paketi ile, Visual Studio Kurumsal 2019 çalıştırılıyor
Kodum : Demoda, CreateWebHostBuilder (string [] args) yöntemi ile bir IWebHostBuilder oluşturdular:
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
{
options.Connect(settings["ConnectionStrings:AzureConfiguration"])
.Use(keyFilter: "TestApp:*")
.WatchAndReloadAll(key: "TestApp:Sentinel", pollInterval: TimeSpan.FromSeconds(5));
});
})
.UseStartup<Startup>();
}
Mevcut belgeleri kullanarak da bu şekilde denedim:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var settings = config.Build();
config.AddAzureAppConfiguration(options =>
{
// fetch connection string from local config. Could use KeyVault, or Secrets as well.
options.Connect(settings["ConnectionStrings:AzureConfiguration"])
// filter configs so we are only searching against configs that meet this pattern
.Use(keyFilter: "WebApp:*")
.ConfigureRefresh(refreshOptions =>
{
// In theory, when this value changes, on the next refresh operation, the config will update all modified configs since it was last refreshed.
refreshOptions.Register("WebApp:Sentinel", true);
refreshOptions.Register("WebApp:Settings:BackgroundColor", false);
refreshOptions.Register("WebApp:Settings:FontColor", false);
refreshOptions.Register("WebApp:Settings:FontSize", false);
refreshOptions.Register("WebApp:Settings:Message", false);
});
});
})
.UseStartup<Startup>();
Sonra, başlangıç sınıfımda:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<Settings>(Configuration.GetSection("WebApp:Settings"));
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseAzureAppConfiguration();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
ve son olarak ayarlarım yapılandırma modelim:
public class Settings
{
public string BackgroundColor { get; set; }
public long FontSize { get; set; }
public string FontColor { get; set; }
public string Message { get; set; }
}
Şimdi, denetleyicimde, bu ayarları alıp görünümde görüntülenecek bir görünüm çantasına atıyorum.
public class HomeController : Controller
{
private readonly Settings _Settings;
public HomeController(IOptionsSnapshot<Settings> settings)
{
_Settings = settings.Value;
}
public IActionResult Index()
{
ViewData["BackgroundColor"] = _Settings.BackgroundColor;
ViewData["FontSize"] = _Settings.FontSize;
ViewData["FontColor"] = _Settings.FontColor;
ViewData["Message"] = _Settings.Message;
return View();
}
}
Değişiklikleri görüntülemek için basit bir görünüm:
<!DOCTYPE html>
<html lang="en">
<style>
body {
background-color: @ViewData["BackgroundColor"]
}
h1 {
color: @ViewData["FontColor"];
font-size: @ViewData["FontSize"];
}
</style>
<head>
<title>Index View</title>
</head>
<body>
<h1>@ViewData["Message"]</h1>
</body>
</html>
Yapılandırmayı ilk kez aşağı çekmeyi başarabilirim, ancak yenileme işlevselliği hiçbir şekilde çalışmıyor gibi görünüyor.
Son örnekte, sentinel herhangi bir yeni değere ayarlandığında yapılandırmaların güncellenmesini veya en azından değiştirildikten 30 saniye sonra bir değeri güncellemesini bekledim. Bekleme süresi değerleri güncellemez ve yalnızca uygulamanın tamamen kapatılması ve yeniden başlatılması yeni yapılandırmayı yükler.
Güncelleme: App eklemeAzureAppConfiguration (); Başlangıçta yapılandırma yönteminde ve yapılandırma için önbellekte açık bir zaman aşımı ayarlandığında, yenileme yönteminin belirli bir süre sonra yenilenmesi düzeltildi, ancak sentinel işlevselliği hala çalışmıyor ve yenileme yöntemindeki updateAll bayrağı çalışmıyor.
ConfigureServices
Startuop.cs'taki yönteminizin bir yerinde bazı yapılandırma bağları bekledim, örneğin services.Configure<LogSettings>(configuration.GetSection("LogSettings"));