我将尝试创建自定义cinfig提供程序,该提供程序将从数据库中获取密钥。正如在手册中所写的那样,我创建了这个提供程序并且它的工作正常。所有键都在开始时加载,一切正常。
但是现在我尝试使用IOptionsSnapshot并重新加载来自db的密钥。但没有任何反应。
任何人都可以告诉我作品出错了。这是我的代码:
{"Image":"[object HTMLImageElement]"}---Image was uploaded
我做了什么才开始工作:
public class EFConfigProvider : ConfigurationProvider
{
private DateTime lastLoaded;
public EFConfigProvider(Action<DbContextOptionsBuilder> optionsAction)
{
OptionsAction = optionsAction;
lastLoaded = DateTime.Now;
ChangeToken.OnChange(
() => Watch(),
() => {
Thread.Sleep(250);
this.Load();
});
}
public new IChangeToken GetReloadToken()
{
return Watch();
}
Action<DbContextOptionsBuilder> OptionsAction { get; }
// Load config data from EF DB.
public override void Load()
{
this.Data.Clear();
var builder = new DbContextOptionsBuilder<ConfigContext>();
OptionsAction(builder);
using (var dbContext = new ConfigContext(builder.Options))
{
// Save Load Fact
dbContext.SaveLoadFact();
// Load Partners Settings
GetPartners(dbContext);
}
}
private IChangeToken Watch()
{
return new DatabaseChangeToken();
}
}
public class DatabaseChangeToken : IChangeToken
{
public bool HasChanged
{
get
{
return true;
}
}
public bool ActiveChangeCallbacks => false;
public IDisposable RegisterChangeCallback(Action<object> callback, object state) => EmptyDisposable.Instance;
internal class EmptyDisposable : IDisposable
{
public static EmptyDisposable Instance { get; } = new EmptyDisposable();
private EmptyDisposable() { }
public void Dispose() { }
}
}
private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();
// Start Periodic task to refresh the DB
PeriodicTask.Run(() =>
{
//Refresh();
OnReload();
}, TimeSpan.FromSeconds(reload));
public class PeriodicTask
{
public static async Task Run(Action action, TimeSpan period, CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(period, cancellationToken);
if (!cancellationToken.IsCancellationRequested)
action();
}
}
public static Task Run(Action action, TimeSpan period)
{
return Run(action, period, CancellationToken.None);
}
}
protected new void OnReload()
{
var previousToken = Interlocked.Exchange(ref _reloadToken, new ConfigurationReloadToken());
previousToken.OnReload();
}
答案 0 :(得分:0)
已更新:我发现覆盖exec(open("./lib/@file_directory/my_classes.py").read())
会中断更改通知(我正在使用OnReload()
,但未看到更改)。因此,我更改了实现以不这样做。它正在调用默认的OptionsMonitor
,该OnReload()
处理OptionsMonitor
的更改通知。
您更新后的实施确实帮助了我,所以谢谢您!
除了使用自定义PeriodicTask
之外,您还可以使用documentation。效果是一样的。
这是我的实现,它每5分钟重新加载一次数据:
using System;
using System.Linq;
using System.Threading;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;
using Timer = System.Timers.Timer;
namespace MyProject.Classes.Configuration {
public class MyConfigProvider : ConfigurationProvider {
private readonly DbContextOptions<MyDbContext> _dbOptions;
private readonly Timer _reloadTimer = new Timer();
private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();
public MyConfigProvider(Action<DbContextOptionsBuilder> dbOptionsAction) {
var builder = new DbContextOptionsBuilder<MyDbContext>();
dbOptionsAction(builder);
_dbOptions = builder.Options;
_reloadTimer.AutoReset = false;
_reloadTimer.Interval = TimeSpan.FromMinutes(5).TotalMilliseconds;
_reloadTimer.Elapsed += (s, e) => { Load(); };
}
public override void Load() {
try {
using (var db = new MyDbContext(_dbOptions)) {
var settings = db.Settings.AsNoTracking().ToList();
Data.Clear();
foreach (var s in settings) {
Data.Add(s.Name, s.Value);
}
}
OnReload();
} finally {
_reloadTimer.Start();
}
}
}
}
答案 1 :(得分:-2)
我有相同的要求,我找到了你的代码,我尝试了同样的事情,但没有工作。
但是你的代码和其他一些调查引导我提示。
public class CustomConfigurationProvider : ConfigurationProvider
{
private readonly string applicationName;
private readonly bool reloadOnChange;
private readonly IConfiguration configuration;
public CustomConfigurationProvider(string applicationName, bool reloadOnChange)
{
this.applicationName = applicationName;
this.reloadOnChange = reloadOnChange;
if(reloadOnChange)
{
ChangeToken.OnChange(
() => GetReloadToken(), // listener to token change
() =>
{
Thread.Sleep(250);
this.Load();
});
}
}
public override async void Load()
{
Data.Clear();
Data = read data from database;
if (Condition to check if data in database changed)
{
OnReload(); // This will create new token and trigger change so what is register in OnChange above will be called again which is this.Load()
}
}
}
和
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/primitives/change-tokens
希望这有帮助。