Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
aritchie committed Jul 8, 2024
1 parent ba875d8 commit 048e7d7
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 18 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Remote Configuration Provider


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)

This library works great with .NET MAUI and ASP.NET Core applications
6 changes: 3 additions & 3 deletions samples/Sample/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Shiny.Extensions.Configuration.Remote.Maui;
using Shiny;

namespace Sample;

Expand All @@ -11,13 +11,13 @@ public static MauiApp CreateMauiApp()
.CreateBuilder()
.UseMauiApp<App>();

// we load the default/builtin accesstoken here
// we load the default configuration uri here
builder.Configuration.AddJsonPlatformBundle();

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

// The extension method `BindConfiguration` is part of Microsoft.Extensions.Options.ConfigurationExtensions - don't hate the messenger
builder.Services.AddOptions<MyConfig>().BindConfiguration("");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
namespace Shiny.Extensions.Configuration.Remote.Maui;
using Microsoft.Extensions.Configuration;
using Shiny.Extensions.Configuration.Remote;

namespace Shiny;


public static class MauiAppBuilderExtensions
{
public static IConfigurationBuilder AddRemoteMaui(
this IConfigurationBuilder builder,
string configurationUri,
string configurationFileName = "remotesettings.json",
Func<RemoteConfig, CancellationToken, Task<object>>? getData = null)
{
return builder.AddRemote(
Path.Combine(FileSystem.AppDataDirectory, configurationFileName),
configurationUri,
getData,
false,
null
);
}

public static MauiAppBuilder AddRemoteConfigurationMaui(
this MauiAppBuilder builder,
Func<CancellationToken, Task<object>>? getData = null,
string configurationUri,
Func<RemoteConfig, CancellationToken, Task<object>>? getData = null,
string configurationFileName = "remotesettings.json"
)
{
builder.Configuration.AddRemote(
Path.Combine(FileSystem.AppDataDirectory, configurationFileName),
config => config["ConfigurationUri"]!,
configurationUri,
getData,
false,
builder.Services
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ public static class ConfigurationExtensions
public static IConfigurationBuilder AddRemote(
this IConfigurationBuilder builder,
string configurationFilePath,
Func<IConfiguration, string> getConfigurationUri,
Func<CancellationToken, Task<object>>? getData = null,
string configurationUri,
Func<RemoteConfig, CancellationToken, Task<object>>? getData = null,
bool waitForRemoteLoad = true,
IServiceCollection? services = null
)
{
builder.AddJsonFile(configurationFilePath, true, true);
var configuration = builder.Build();
var uri = getConfigurationUri.Invoke(configuration);
builder.Add(new RemoteConfigurationSource(new RemoteConfig(
uri,
configurationUri,
configuration,
waitForRemoteLoad,
configurationFilePath
), getData, services));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System.Text.Json;
using System.Text.Json.Nodes;

namespace Shiny.Extensions.Configuration.Remote.Infrastructure;


public class RemoteConfigurationProvider(RemoteConfig config, Func<CancellationToken, Task<object>>? getData) : ConfigurationProvider, IRemoteConfigurationProvider
public class RemoteConfigurationProvider(RemoteConfig config, Func<RemoteConfig, CancellationToken, Task<object>>? getData) : ConfigurationProvider, IRemoteConfigurationProvider

Check warning on line 7 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationProvider.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationProvider'

Check warning on line 7 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationProvider.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationProvider.RemoteConfigurationProvider(RemoteConfig, Func<RemoteConfig, CancellationToken, Task<object>>?)'

Check warning on line 7 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationProvider.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationProvider'

Check warning on line 7 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationProvider.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationProvider.RemoteConfigurationProvider(RemoteConfig, Func<RemoteConfig, CancellationToken, Task<object>>?)'
{
const string LAST_LOAD_KEY = "__LastLoaded";

Expand Down Expand Up @@ -64,17 +65,19 @@ public async Task LoadAsync(CancellationToken cancellationToken = default)
if (getData == null)
{
this.httpClient ??= new();
var content = await this.httpClient
var json = await this.httpClient
.GetStringAsync(config.Uri, cancellationToken)
.ConfigureAwait(false);

JsonObject.Parse(json);
await this.WriteJson(json, cancellationToken).ConfigureAwait(false);
}
else
{
var obj = await getData.Invoke(cancellationToken).ConfigureAwait(false);
var obj = await getData.Invoke(config, cancellationToken).ConfigureAwait(false);
var json = JsonSerializer.Serialize(obj);
await this.WriteJson(json, cancellationToken);
await this.WriteJson(json, cancellationToken).ConfigureAwait(false);
}

}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Shiny.Extensions.Configuration.Remote.Infrastructure;


public class RemoteConfigurationSource(RemoteConfig config, Func<CancellationToken, Task<object>>? getData, IServiceCollection? services) : IConfigurationSource
public class RemoteConfigurationSource(RemoteConfig config, Func<RemoteConfig, CancellationToken, Task<object>>? getData, IServiceCollection? services) : IConfigurationSource

Check warning on line 6 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationSource.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationSource'

Check warning on line 6 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationSource.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationSource.RemoteConfigurationSource(RemoteConfig, Func<RemoteConfig, CancellationToken, Task<object>>?, IServiceCollection?)'

Check warning on line 6 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationSource.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationSource'

Check warning on line 6 in src/Shiny.Extensions.Configuration.Remote/Infrastructure/RemoteConfigurationSource.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'RemoteConfigurationSource.RemoteConfigurationSource(RemoteConfig, Func<RemoteConfig, CancellationToken, Task<object>>?, IServiceCollection?)'
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
Expand Down
3 changes: 2 additions & 1 deletion src/Shiny.Extensions.Configuration.Remote/RemoteConfig.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
namespace Shiny.Extensions.Configuration.Remote;

public record RemoteConfig(
string Uri,
string Uri,
IConfiguration CurrentConfiguration,
bool WaitForLoadOnStartup = false,
string ConfigurationFilePath = "remotesettings.json"
);

0 comments on commit 048e7d7

Please sign in to comment.