【发布时间】:2018-02-13 15:25:26
【问题描述】:
我将尝试创建将从数据库中获取密钥的自定义配置提供程序。正如手册中所写,我创建了这个提供程序,它工作正常。所有键都在启动时加载,一切正常。
但现在我正在尝试使用 IOptionsSnapshot 并在更改时从 db 重新加载密钥。但是什么也没发生。
谁能告诉我出了什么问题?这是我的代码:
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() { }
}
}
我做了什么来开始工作:
- 我在类中添加了 EFConfigProvider 变量
private ConfigurationReloadToken _reloadToken = new ConfigurationReloadToken();
- 我在构造函数中添加
// Start Periodic task to refresh the DB
PeriodicTask.Run(() =>
{
//Refresh();
OnReload();
}, TimeSpan.FromSeconds(reload));
- 我为 periodTask 添加类
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();
}
- 添加使用更改令牌的更改
ChangeToken.OnChange(
() => { return this._reloadToken; },
() => {
Thread.Sleep(250);
this.Load();
});
【问题讨论】:
标签: c# asp.net-core configuration