You've already forked Extensions.Configuration.EntityFrameworkCore
Working implementation
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# RAIC.Extensions.Configuration.EntityFrameworkCore.SqlServer
|
||||
|
||||
This library enhances `RAIC.Extensions.Configuration.EntityFrameworkCore` with support for reload on update the via the
|
||||
[query change notifications](https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql/query-notifications-in-sql-server) capability exposed by
|
||||
`Microsoft.Data.SqlClient.SqlDependency` along with SQL Server's
|
||||
[Change Tracking](https://learn.microsoft.com/en-us/sql/relational-databases/track-changes/about-change-tracking-sql-server) feature.
|
||||
|
||||
## Goals
|
||||
1. No polling!
|
||||
1. Updates happen in background via worker service (`IHostedService`)
|
||||
1. Only update settings which change rather than reloading all of them
|
||||
|
||||
|
||||
## Requirements
|
||||
* .NET 8
|
||||
|
||||
## Gotchas
|
||||
* Won't work with Azure SQL until Microsoft adds/enables Service Broker support
|
||||
* Setting values cannot be `null` (as signified by the `RequiredAttribute` on `ISetting.Value`)
|
||||
|
||||
## Known Issues
|
||||
* Not tested under load
|
||||
|
||||
## Configuration Options
|
||||
There is a single property which can be configured (cf. the `SqlServerNotificationConfigurationReloaderOptions` POCO)
|
||||
1. `ConnectionString` - the full connection string for the SQL Server instance
|
||||
|
||||
## Setup
|
||||
For `SqlServerNotificationConfigurationReloader` to work it requires Change Tracking to be enable on the `Settings` table (and therefore also on the database itself)
|
||||
eg:
|
||||
|
||||
```sql
|
||||
ALTER DATABASE myDatabase
|
||||
SET CHANGE_TRACKING = ON (AUTO_CLEANUP = ON);
|
||||
|
||||
ALTER TABLE dbo.Settings
|
||||
ENABLE CHANGE_TRACKING;
|
||||
```
|
||||
|
||||
Reccommend adding your SQL to the migration which adds the `Settings` table/view (or a new migration if that table/view already exists).
|
||||
|
||||
## Usage Example
|
||||
|
||||
```csharp
|
||||
|
||||
using RAIC.Extensions.Configuration.EntityFrameworkCore;
|
||||
using RAIC.Extensions.Configuration.EntityFrameworkCore.Extensions;
|
||||
using RAIC.Extensions.Configuration.EntityFrameworkCore.SqlServer.Extensions;
|
||||
|
||||
[Table("settings", Schema = "dbo")] // Need to explicitly set schema somehow, this is one way to do it
|
||||
public record Setting : ISetting
|
||||
{
|
||||
[Key]
|
||||
public required string Key { get; set; }
|
||||
|
||||
[Required]
|
||||
public required string Value { get; set; }
|
||||
}
|
||||
|
||||
public class MyDbContext(DbContextOptions<MyDbContext> options) : DbContext(options), ISettingsDbContext<DbSet<Setting>,Setting>
|
||||
{
|
||||
public DbSet<Setting> Settings { get; set; }
|
||||
}
|
||||
|
||||
|
||||
var builder = Host.CreateApplicationBuilder(args); // or WebApplication.CreateBuilder(args);
|
||||
|
||||
// build an initial configuration
|
||||
builder.Configuration.AddJsonFile("appsettings.json")
|
||||
...
|
||||
.AddUserSecrets<Program>(); // or wherever your connection string lives
|
||||
|
||||
builder.Configuration.AddDbSet<MyDbContext, Setting>(dbContextOptions => dbContextOptions.UseSqlServer(builder.Configuration.GetConnectionString("Default")));
|
||||
|
||||
...
|
||||
// Add the SqlServerNotificationConfigurationReloader background service and supporting services to obtain setting reloading functionalty
|
||||
builder.Services.AddSqlServerNotificationConfigurationReloadService<MyDbContext, Settings>(); // uses connection string from MyDbContext. Other overrides exist if this doesn't work for you - see cods docs
|
||||
|
||||
await builder.Build().RunAsync(); // use config as normal
|
||||
|
||||
```
|
||||
|
||||
Read more about [Configuration](https://docs.microsoft.com/en-us/dotnet/core/extensions/configuration) and [Options](https://docs.microsoft.com/en-us/dotnet/core/extensions/options) on the Microsoft Docs site.
|
||||
Reference in New Issue
Block a user