Skip to content

Commit 048e7d7

Browse files
committed
Fixes
1 parent ba875d8 commit 048e7d7

File tree

7 files changed

+44
-18
lines changed

7 files changed

+44
-18
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# Remote Configuration Provider
2-
2+
3+
Work with the power of Microsoft.Extensions.Configuration while still being able to retrieve most configuration from a server (much like secrets). For mobile, get the added benefit of having "cached" configuration in cases where connectivity is not available. This allows you to update things like license keys, data endpoints, & more. Could you do this without this library? Yes - BUT you don't get IOptionsMonitor and have to work with another mediation service everywhere (if remote, use that value, else pull from local)
4+
5+
This library works great with .NET MAUI and ASP.NET Core applications

samples/Sample/MauiProgram.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Shiny.Extensions.Configuration.Remote.Maui;
1+
using Shiny;
22

33
namespace Sample;
44

@@ -11,13 +11,13 @@ public static MauiApp CreateMauiApp()
1111
.CreateBuilder()
1212
.UseMauiApp<App>();
1313

14-
// we load the default/builtin accesstoken here
14+
// we load the default configuration uri here
1515
builder.Configuration.AddJsonPlatformBundle();
1616

1717
// if remote has requested past values, those will be available here through configuration
1818
// so you could basically change the URI & AccessKey below
1919
// calling this method adds IRemoteConfigurationProvider to DI which allows you to await the configuration in a startup page if needed
20-
builder.AddRemoteConfigurationMaui();
20+
builder.AddRemoteConfigurationMaui(builder.Configuration.GetValue<string>("ConfigurationUri")!);
2121

2222
// The extension method `BindConfiguration` is part of Microsoft.Extensions.Options.ConfigurationExtensions - don't hate the messenger
2323
builder.Services.AddOptions<MyConfig>().BindConfiguration("");

src/Shiny.Extensions.Configuration.Remote.Maui/MauiAppBuilderExtensions.cs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
1-
namespace Shiny.Extensions.Configuration.Remote.Maui;
1+
using Microsoft.Extensions.Configuration;
2+
using Shiny.Extensions.Configuration.Remote;
3+
4+
namespace Shiny;
25

36

47
public static class MauiAppBuilderExtensions
58
{
9+
public static IConfigurationBuilder AddRemoteMaui(
10+
this IConfigurationBuilder builder,
11+
string configurationUri,
12+
string configurationFileName = "remotesettings.json",
13+
Func<RemoteConfig, CancellationToken, Task<object>>? getData = null)
14+
{
15+
return builder.AddRemote(
16+
Path.Combine(FileSystem.AppDataDirectory, configurationFileName),
17+
configurationUri,
18+
getData,
19+
false,
20+
null
21+
);
22+
}
23+
624
public static MauiAppBuilder AddRemoteConfigurationMaui(
725
this MauiAppBuilder builder,
8-
Func<CancellationToken, Task<object>>? getData = null,
26+
string configurationUri,
27+
Func<RemoteConfig, CancellationToken, Task<object>>? getData = null,
928
string configurationFileName = "remotesettings.json"
1029
)
1130
{
1231
builder.Configuration.AddRemote(
1332
Path.Combine(FileSystem.AppDataDirectory, configurationFileName),
14-
config => config["ConfigurationUri"]!,
33+
configurationUri,
1534
getData,
1635
false,
1736
builder.Services

src/Shiny.Extensions.Configuration.Remote/ConfigurationExtensions.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ public static class ConfigurationExtensions
1919
public static IConfigurationBuilder AddRemote(
2020
this IConfigurationBuilder builder,
2121
string configurationFilePath,
22-
Func<IConfiguration, string> getConfigurationUri,
23-
Func<CancellationToken, Task<object>>? getData = null,
22+
string configurationUri,
23+
Func<RemoteConfig, CancellationToken, Task<object>>? getData = null,
2424
bool waitForRemoteLoad = true,
2525
IServiceCollection? services = null
2626
)
2727
{
2828
builder.AddJsonFile(configurationFilePath, true, true);
2929
var configuration = builder.Build();
30-
var uri = getConfigurationUri.Invoke(configuration);
3130
builder.Add(new RemoteConfigurationSource(new RemoteConfig(
32-
uri,
31+
configurationUri,
32+
configuration,
3333
waitForRemoteLoad,
3434
configurationFilePath
3535
), getData, services));

src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationProvider.cs

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
using System.Text.Json;
2+
using System.Text.Json.Nodes;
23

34
namespace Shiny.Extensions.Configuration.Remote.Infrastructure;
45

56

6-
public class RemoteConfigurationProvider(RemoteConfig config, Func<CancellationToken, Task<object>>? getData) : ConfigurationProvider, IRemoteConfigurationProvider
7+
public class RemoteConfigurationProvider(RemoteConfig config, Func<RemoteConfig, CancellationToken, Task<object>>? getData) : ConfigurationProvider, IRemoteConfigurationProvider
78
{
89
const string LAST_LOAD_KEY = "__LastLoaded";
910

@@ -64,17 +65,19 @@ public async Task LoadAsync(CancellationToken cancellationToken = default)
6465
if (getData == null)
6566
{
6667
this.httpClient ??= new();
67-
var content = await this.httpClient
68+
var json = await this.httpClient
6869
.GetStringAsync(config.Uri, cancellationToken)
6970
.ConfigureAwait(false);
71+
72+
JsonObject.Parse(json);
73+
await this.WriteJson(json, cancellationToken).ConfigureAwait(false);
7074
}
7175
else
7276
{
73-
var obj = await getData.Invoke(cancellationToken).ConfigureAwait(false);
77+
var obj = await getData.Invoke(config, cancellationToken).ConfigureAwait(false);
7478
var json = JsonSerializer.Serialize(obj);
75-
await this.WriteJson(json, cancellationToken);
79+
await this.WriteJson(json, cancellationToken).ConfigureAwait(false);
7680
}
77-
7881
}
7982
finally
8083
{

src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationSource.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Shiny.Extensions.Configuration.Remote.Infrastructure;
44

55

6-
public class RemoteConfigurationSource(RemoteConfig config, Func<CancellationToken, Task<object>>? getData, IServiceCollection? services) : IConfigurationSource
6+
public class RemoteConfigurationSource(RemoteConfig config, Func<RemoteConfig, CancellationToken, Task<object>>? getData, IServiceCollection? services) : IConfigurationSource
77
{
88
public IConfigurationProvider Build(IConfigurationBuilder builder)
99
{
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
namespace Shiny.Extensions.Configuration.Remote;
22

33
public record RemoteConfig(
4-
string Uri,
4+
string Uri,
5+
IConfiguration CurrentConfiguration,
56
bool WaitForLoadOnStartup = false,
67
string ConfigurationFilePath = "remotesettings.json"
78
);

0 commit comments

Comments
 (0)