Skip to content

Commit 4c08541

Browse files
Merge pull request #12 from Stravaig-Projects/#2/create-config-provider
Create basic provider
2 parents cb0e8cb + e96ee9f commit 4c08541

26 files changed

+561
-21
lines changed

release-notes/wip-release-notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Date: ???
1111
### Miscellaneous
1212

1313
- #1: Initial set up
14+
- #2: Create the initial provider
1415

1516
### Dependabot
1617

src/Example/Example.csproj

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<Nullable>enable</Nullable>
7+
<UserSecretsId>7f191ac2-a110-4f9d-989f-0c4afa1d9e45</UserSecretsId>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\Stravaig.Configuration.SqlServer\Stravaig.Configuration.SqlServer.csproj" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.0" />
16+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
17+
<PackageReference Include="Microsoft.FeatureManagement" Version="2.4.0" />
18+
<PackageReference Include="Stravaig.Configuration.Diagnostics.Logging" Version="1.0.4" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<None Remove="appsettings.json" />
23+
<Content Include="appsettings.json">
24+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
25+
</Content>
26+
</ItemGroup>
27+
28+
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Example;
2+
3+
public class MyFeatureConfiguration
4+
{
5+
public int? SomeNumber { get; set; }
6+
7+
public string? SomeString { get; set; }
8+
9+
public double? SomeFloatingPointNumber { get; set; }
10+
11+
public bool? SomeBoolean { get; set; }
12+
}

src/Example/Program.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Example;
2+
using Microsoft.Extensions.Configuration;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Hosting;
5+
using Microsoft.Extensions.Logging;
6+
using Microsoft.FeatureManagement;
7+
using Stravaig.Configuration.SqlServer;
8+
9+
await Host.CreateDefaultBuilder(args)
10+
.ConfigureAppConfiguration(builder =>
11+
{
12+
builder.AddUserSecrets<Program>();
13+
builder.AddSqlServer(opts =>
14+
{
15+
opts.FromExistingConfiguration();
16+
});
17+
})
18+
.ConfigureLogging(builder =>
19+
{
20+
builder.AddConsole();
21+
builder.AddDebug();
22+
})
23+
.ConfigureServices((ctx, services) =>
24+
{
25+
IConfigurationRoot configRoot = (IConfigurationRoot) ctx.Configuration;
26+
services.AddTransient<IHostedService, TheHostedService>();
27+
services.AddSingleton(configRoot);
28+
services.Configure<MyFeatureConfiguration>(configRoot.GetSection("MyConfiguration"));
29+
services.AddFeatureManagement(configRoot.GetSection("FeatureManager"));
30+
})
31+
.RunConsoleAsync();

src/Example/TheHostedService.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using System;
2+
using System.Text.Json;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using System.Timers;
6+
using Microsoft.Extensions.Configuration;
7+
using Microsoft.Extensions.Hosting;
8+
using Microsoft.Extensions.Logging;
9+
using Microsoft.Extensions.Options;
10+
using Microsoft.FeatureManagement;
11+
using Stravaig.Configuration.Diagnostics.Logging;
12+
using Timer = System.Timers.Timer;
13+
14+
15+
namespace Example;
16+
17+
public class TheHostedService : IHostedService, IDisposable
18+
{
19+
private readonly ILogger<TheHostedService> _logger;
20+
private readonly IConfigurationRoot _configRoot;
21+
private readonly IFeatureManager _featureManager;
22+
private readonly IOptionsMonitor<MyFeatureConfiguration> _featureValues;
23+
private readonly Timer _timer;
24+
25+
public TheHostedService(
26+
ILogger<TheHostedService> logger,
27+
IConfigurationRoot configRoot,
28+
IFeatureManager featureManager,
29+
IOptionsMonitor<MyFeatureConfiguration> featureValues)
30+
{
31+
_logger = logger;
32+
_configRoot = configRoot;
33+
_featureManager = featureManager;
34+
_featureValues = featureValues;
35+
_timer = new Timer(10000);
36+
_timer.Elapsed += TimerOnElapsed;
37+
featureValues.OnChange((_, s) =>
38+
{
39+
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] Change Detected. {s}");
40+
});
41+
}
42+
43+
private async void TimerOnElapsed(object? sender, ElapsedEventArgs e)
44+
{
45+
var jsonOptions = new JsonSerializerOptions()
46+
{
47+
WriteIndented = true,
48+
};
49+
string json = JsonSerializer.Serialize(_featureValues.CurrentValue, jsonOptions);
50+
Console.Clear();
51+
_logger.LogInformation(
52+
"At {Time} the object looks like:\n{Json}",
53+
e.SignalTime,
54+
json);
55+
await foreach (string feature in _featureManager.GetFeatureNamesAsync())
56+
{
57+
var state = await _featureManager.IsEnabledAsync(feature);
58+
_logger.LogInformation("{Feature} : {State}", feature, state);
59+
}
60+
_logger.LogConfigurationValuesAsInformation(_configRoot.GetSection("MyConfiguration"));
61+
}
62+
63+
public Task StartAsync(CancellationToken cancellationToken)
64+
{
65+
_logger.LogInformation("The hosted service is starting.");
66+
_logger.LogProvidersAsInformation(_configRoot);
67+
_timer.Enabled = true;
68+
return Task.CompletedTask;
69+
}
70+
71+
public Task StopAsync(CancellationToken cancellationToken)
72+
{
73+
_timer.Enabled = false;
74+
_logger.LogInformation("The hosted service is ending.");
75+
return Task.CompletedTask;
76+
}
77+
78+
public void Dispose()
79+
{
80+
_timer.Dispose();
81+
}
82+
}

src/Example/appsettings.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"Stravaig": {
3+
"AppConfiguration": {
4+
"SchemaName": "Stravaig",
5+
"TableName": "AppConfiguration",
6+
"RefreshSeconds": 15,
7+
"ConnectionString": "*** Found in User Secrets ***"
8+
}
9+
},
10+
"FeatureManager": {
11+
"FeatureA": true,
12+
"FeatureB": {}
13+
},
14+
"MyConfiguration": {
15+
"SomeNumber": 123,
16+
"SomeString": "A value from appsettings",
17+
"SomeBoolean": "true",
18+
"SomeFloatingPointNumber": 123.456
19+
}
20+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- Run this in to your database. You can change the schema to suit if you need to.
2+
3+
CREATE SCHEMA Stravaig;
4+
GO
5+
CREATE TABLE Stravaig.AppConfiguration
6+
(
7+
ConfigKey NVARCHAR(1024) PRIMARY KEY CLUSTERED,
8+
ConfigValue NVARCHAR(MAX)
9+
);
10+
GO

src/SQL Scripts/CreateNewConfigurationValue.sql

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
BEGIN TRANSACTION
2+
3+
UPDATE Stravaig.AppConfiguration
4+
SET ConfigValue = 'A different value from the database.'
5+
WHERE ConfigKey = 'MyConfiguration:SomeString'
6+
7+
8+
UPDATE Stravaig.AppConfiguration
9+
SET ConfigValue = 'true'
10+
WHERE ConfigKey = 'FeatureManager:FeatureC'
11+
12+
COMMIT TRANSACTION
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace Stravaig.Configuration.SqlServer.Tests;
5+
6+
public class FakeDataLoader : IDataLoader
7+
{
8+
public KeyValuePair<string, string>[] FakeData { get; set; } = Array.Empty<KeyValuePair<string, string>>();
9+
public IEnumerable<KeyValuePair<string, string>> RetrieveData(SqlServerConfigurationSource source)
10+
{
11+
return FakeData;
12+
}
13+
}

0 commit comments

Comments
 (0)