Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,21 +102,24 @@ public void ConfigureServices(IServiceCollection services)
{
.....
// Configure with an action
services.AddGotenbergSharpClient(options =>
{
options.ServiceUrl = new Uri("http://localhost:3000");
options.TimeOut = TimeSpan.FromMinutes(5);
options.BasicAuthUsername = "username";
options.BasicAuthPassword = "password";
// Configure retry policy
options.RetryPolicy = new RetryPolicyOptions
services.AddOptions<GotenbergSharpClientOptions>()
.Configure(options =>
{
Enabled = true,
RetryCount = 4,
BackoffPower = 1.5,
LoggingEnabled = true
};
});
options.ServiceUrl = new Uri("http://localhost:3000");
options.TimeOut = TimeSpan.FromMinutes(5);
options.BasicAuthUsername = "username";
options.BasicAuthPassword = "password";
// Configure retry policy
options.RetryPolicy = new RetryOptions
{
Enabled = true,
RetryCount = 4,
BackoffPower = 1.5,
LoggingEnabled = true
};
});

services.AddGotenbergSharpClient();
.....
}
```
Expand All @@ -125,18 +128,19 @@ public void ConfigureServices(IServiceCollection services)
```csharp
public void ConfigureServices(IServiceCollection services)
{
.....
.....
services.AddOptions<GotenbergSharpClientOptions>()
.Bind(Configuration.GetSection(nameof(GotenbergSharpClient)));
.Bind(Configuration.GetSection(nameof(GotenbergSharpClient)))
.PostConfigure(options =>
{
// Override or add settings programmatically (runs after binding)
options.TimeOut = TimeSpan.FromMinutes(10); // Override timeout
options.BasicAuthUsername = Environment.GetEnvironmentVariable("GOTENBERG_USER");
options.BasicAuthPassword = Environment.GetEnvironmentVariable("GOTENBERG_PASS");
});

// Override or add settings programmatically
services.AddGotenbergSharpClient(options =>
{
options.TimeOut = TimeSpan.FromMinutes(10); // Override timeout
options.BasicAuthUsername = Environment.GetEnvironmentVariable("GOTENBERG_USER");
options.BasicAuthPassword = Environment.GetEnvironmentVariable("GOTENBERG_PASS");
});
.....
services.AddGotenbergSharpClient();
.....
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,78 @@ public static class TypedClientServiceCollectionExtensions
{
/// <summary>
/// Registers GotenbergSharpClient with dependency injection using configured options.
/// Configure options via appsettings.json or by calling services.Configure&lt;GotenbergSharpClientOptions&gt;().
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="configureClientOptions">Optional function to configure client options after they are retrieved.</param>
/// <returns>An IHttpClientBuilder for further configuration.</returns>
/// <exception cref="ArgumentNullException">Thrown when services is null.</exception>
/// <remarks>
/// This method configures the HttpClient with automatic compression, retry policies, and basic authentication if
/// credentials are provided.
/// Options should be configured in the "GotenbergSharpClient" section of appsettings.json or programmatically.
/// <para>
/// This method registers the GotenbergSharpClient with automatic compression, retry policies,
/// and basic authentication if credentials are provided in the options.
/// </para>
/// <para>
/// Options must be registered before calling this method using
/// standard .NET options configuration methods.
/// The client retrieves options from the DI container using <c>IOptions&lt;TOptions&gt;</c>.
/// </para>
/// <para>
/// Example usage:
/// <code>
/// services.AddOptions&lt;GotenbergSharpClientOptions&gt;()
/// .Bind(configuration.GetSection("GotenbergSharpClient"));
/// services.AddGotenbergSharpClient();
/// </code>
/// </para>
/// </remarks>
public static IHttpClientBuilder AddGotenbergSharpClient(
this IServiceCollection services,
Action<GotenbergSharpClientOptions>? configureClientOptions = null)
this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}

return services.AddGotenbergSharpClient((sp, client) =>
return services.AddGotenbergSharpClient<GotenbergSharpClientOptions>();
}

/// <summary>
/// Registers GotenbergSharpClient with dependency injection using configured options.
/// </summary>
/// <typeparam name="TOptions">The options type, must inherit from GotenbergSharpClientOptions.</typeparam>
/// <param name="services">The service collection.</param>
/// <returns>An IHttpClientBuilder for further configuration.</returns>
/// <exception cref="ArgumentNullException">Thrown when services is null.</exception>
/// <remarks>
/// <para>
/// This method registers the GotenbergSharpClient with automatic compression, retry policies,
/// and basic authentication if credentials are provided in the options.
/// </para>
/// <para>
/// Options must be registered before calling this method using
/// standard .NET options configuration methods.
/// The client retrieves options from the DI container using <c>IOptions&lt;TOptions&gt;</c>.
/// </para>
/// <para>
/// Example usage:
/// <code>
/// services.AddOptions&lt;GotenbergSharpClientOptions&gt;()
/// .Bind(configuration.GetSection("GotenbergSharpClient"));
/// services.AddGotenbergSharpClient();
/// </code>
/// </para>
/// </remarks>
public static IHttpClientBuilder AddGotenbergSharpClient<TOptions>(
this IServiceCollection services)
where TOptions : GotenbergSharpClientOptions, new()
{
if (services == null)
{
var ops = GetOptions(sp) ?? new GotenbergSharpClientOptions();
throw new ArgumentNullException(nameof(services));
}

configureClientOptions?.Invoke(ops);
return services.AddGotenbergSharpClient<TOptions>((sp, client) =>
{
var ops = sp.GetRequiredService<IOptions<TOptions>>().Value;

client.Timeout = ops.TimeOut;
client.BaseAddress = ops.ServiceUrl;
Expand All @@ -65,18 +112,92 @@ public static IHttpClientBuilder AddGotenbergSharpClient(
/// Registers GotenbergSharpClient with dependency injection using a custom HttpClient configuration.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="configureClient">Action to configure the HttpClient instance.</param>
/// <param name="configureClientOptions">Optional function to configure client options after they are retrieved.</param>
/// <param name="configureClient">
/// Action to configure the HttpClient instance. The action receives the service provider and HttpClient
/// for custom configuration.
/// </param>
/// <returns>An IHttpClientBuilder for further configuration.</returns>
/// <exception cref="ArgumentNullException">Thrown when configureClient is null.</exception>
/// <remarks>
/// This overload allows full control over HttpClient configuration. The client is configured with
/// automatic compression, timeout handling, and exponential backoff retry policies.
/// <para>
/// This overload allows full control over HttpClient configuration while still using the options
/// for basic authentication and retry policies. The client is configured with automatic compression,
/// timeout handling, and exponential backoff retry policies based on the registered options.
/// </para>
/// <para>
/// Options must be registered before calling this method using
/// standard .NET options configuration methods.
/// </para>
/// <para>
/// Example usage:
/// <code>
/// services.AddOptions&lt;GotenbergSharpClientOptions&gt;()
/// .Bind(configuration.GetSection("GotenbergSharpClient"))
/// .PostConfigure(options =>
/// {
/// options.BasicAuthUsername = "user";
/// options.BasicAuthPassword = "pass";
/// });
///
/// services.AddGotenbergSharpClient((sp, client) =>
/// {
/// // Custom HttpClient configuration
/// client.DefaultRequestHeaders.Add("X-Custom-Header", "value");
/// });
/// </code>
/// </para>
/// </remarks>
public static IHttpClientBuilder AddGotenbergSharpClient(
this IServiceCollection services,
Action<IServiceProvider, HttpClient> configureClient,
Action<GotenbergSharpClientOptions>? configureClientOptions = null)
Action<IServiceProvider, HttpClient> configureClient)
{
return services.AddGotenbergSharpClient<GotenbergSharpClientOptions>(configureClient);
}

/// <summary>
/// Registers GotenbergSharpClient with dependency injection using a custom HttpClient configuration.
/// </summary>
/// <typeparam name="TOptions">The options type, must inherit from GotenbergSharpClientOptions.</typeparam>
/// <param name="services">The service collection.</param>
/// <param name="configureClient">
/// Action to configure the HttpClient instance. The action receives the service provider and HttpClient
/// for custom configuration.
/// </param>
/// <returns>An IHttpClientBuilder for further configuration.</returns>
/// <exception cref="ArgumentNullException">Thrown when configureClient is null.</exception>
/// <remarks>
/// <para>
/// This overload allows full control over HttpClient configuration while still using the options
/// for basic authentication and retry policies. The client is configured with automatic compression,
/// timeout handling, and exponential backoff retry policies based on the registered options.
/// </para>
/// <para>
/// Options must be registered before calling this method using
/// standard .NET options configuration methods.
/// </para>
/// <para>
/// Example usage:
/// <code>
/// services.AddOptions&lt;GotenbergSharpClientOptions&gt;()
/// .Bind(configuration.GetSection("GotenbergSharpClient"))
/// .PostConfigure(options =>
/// {
/// options.BasicAuthUsername = "user";
/// options.BasicAuthPassword = "pass";
/// });
///
/// services.AddGotenbergSharpClient((sp, client) =>
/// {
/// // Custom HttpClient configuration
/// client.DefaultRequestHeaders.Add("X-Custom-Header", "value");
/// });
/// </code>
/// </para>
/// </remarks>
public static IHttpClientBuilder AddGotenbergSharpClient<TOptions>(
this IServiceCollection services,
Action<IServiceProvider, HttpClient> configureClient)
where TOptions : GotenbergSharpClientOptions, new()
{
if (configureClient == null)
{
Expand All @@ -94,9 +215,7 @@ public static IHttpClientBuilder AddGotenbergSharpClient(
}))
.AddHttpMessageHandler(sp =>
{
var ops = GetOptions(sp) ?? new GotenbergSharpClientOptions();

configureClientOptions?.Invoke(ops);
var ops = sp.GetRequiredService<IOptions<TOptions>>().Value;

var hasUsername = !string.IsNullOrWhiteSpace(ops.BasicAuthUsername);
var hasPassword = !string.IsNullOrWhiteSpace(ops.BasicAuthPassword);
Expand All @@ -122,9 +241,4 @@ public static IHttpClientBuilder AddGotenbergSharpClient(

return builder;
}

private static GotenbergSharpClientOptions? GetOptions(IServiceProvider sp)
{
return sp.GetService<IOptions<GotenbergSharpClientOptions>>()?.Value;
}
}
Loading
Loading