Skip to content

Commit

Permalink
Options pattern binding (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonashendrickx authored Mar 19, 2024
1 parent 6a01e85 commit 6223dab
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/Passwordless/Passwordless.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
</ItemGroup>

Expand Down
53 changes: 37 additions & 16 deletions src/Passwordless/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Dynamic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Passwordless;
Expand All @@ -23,32 +24,52 @@ public static IServiceCollection AddPasswordlessSdk(
.PostConfigure(options => options.ApiUrl ??= PasswordlessOptions.CloudApiUrl)
.Validate(options => !string.IsNullOrEmpty(options.ApiSecret), "Passwordless: Missing ApiSecret");

services.AddHttpClient<IPasswordlessClient, PasswordlessClient>((http, sp) =>
// Above call to services.AddOptions<...> only registers IOptions<PasswordlessOptions>, not
// PasswordlessOptions itself, so we need to resolve it manually.
new PasswordlessClient(http, sp.GetRequiredService<IOptions<PasswordlessOptions>>().Value)
);
services.RegisterDependencies();

// TODO: Get rid of this service, all consumers should use the interface
services.AddTransient(sp => (PasswordlessClient)sp.GetRequiredService<IPasswordlessClient>());
return services;
}

/// <summary>
/// Adds and configures Passwordless-related services.
/// </summary>
public static IServiceCollection AddPasswordlessSdk(
this IServiceCollection services,
IConfiguration configuration)
{
services.AddOptions<PasswordlessOptions>()
.Configure(configuration.Bind)
.Validate(options => !string.IsNullOrEmpty(options.ApiSecret), "Passwordless: Missing ApiSecret");

services.RegisterDependencies();

return services;
}


/// <summary>
/// Adds and configures Passwordless-related services.
/// </summary>
/// <param name="services"></param>
/// <param name="section"></param>
/// <returns></returns>
public static IServiceCollection AddPasswordlessSdk(
this IServiceCollection services,
IConfiguration configuration) =>
services.AddPasswordlessSdk(o =>
{
o.ApiUrl = configuration["ApiUrl"] ?? PasswordlessOptions.CloudApiUrl;
string section)
{
services.AddOptions<PasswordlessOptions>().BindConfiguration(section);

o.ApiSecret =
configuration["ApiSecret"] ??
throw new InvalidOperationException("Missing 'ApiSecret' configuration value.");
services.RegisterDependencies();

o.ApiKey = configuration["ApiKey"];
});
return services;
}

private static void RegisterDependencies(this IServiceCollection services)
{
services.AddHttpClient<IPasswordlessClient, PasswordlessClient>((http, sp) =>
new PasswordlessClient(http, sp.GetRequiredService<IOptions<PasswordlessOptions>>().Value)
);

// TODO: Get rid of this service, all consumers should use the interface
services.AddTransient(sp => (PasswordlessClient)sp.GetRequiredService<IPasswordlessClient>());
}
}

0 comments on commit 6223dab

Please sign in to comment.