Added a validation in the `ReCClient` constructor to ensure that an `ILogger` instance is provided when the `LogSuccessfulRequests` option in `ReCClientOptions` is enabled. Throws an `InvalidOperationException` with a detailed message if no logger is injected. The message includes guidance on resolving the issue by either registering a logging provider or disabling the option.
176 lines
7.2 KiB
C#
176 lines
7.2 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
using System;
|
|
using System.Net.Http;
|
|
using ReC.Client.Api;
|
|
|
|
namespace ReC.Client
|
|
{
|
|
/// <summary>
|
|
/// A client for interacting with the ReC API.
|
|
/// </summary>
|
|
public class ReCClient
|
|
{
|
|
private readonly HttpClient _http;
|
|
|
|
/// <summary>
|
|
/// A unique name for the HttpClient used by the ReCClient.
|
|
/// </summary>
|
|
public static readonly string ClientName = Guid.NewGuid().ToString();
|
|
|
|
/// <summary>
|
|
/// Provides access to RecAction endpoints.
|
|
/// </summary>
|
|
public RecActionApi RecActions { get; }
|
|
|
|
/// <summary>
|
|
/// Provides access to Result endpoints.
|
|
/// </summary>
|
|
public ResultApi Results { get; }
|
|
|
|
/// <summary>
|
|
/// Provides access to Profile endpoints.
|
|
/// </summary>
|
|
public ProfileApi Profiles { get; }
|
|
|
|
/// <summary>
|
|
/// Provides access to EndpointAuth endpoints.
|
|
/// </summary>
|
|
public EndpointAuthApi EndpointAuth { get; }
|
|
|
|
/// <summary>
|
|
/// Provides access to EndpointParams endpoints.
|
|
/// </summary>
|
|
public EndpointParamsApi EndpointParams { get; }
|
|
|
|
/// <summary>
|
|
/// Provides access to Endpoints endpoints.
|
|
/// </summary>
|
|
public EndpointsApi Endpoints { get; }
|
|
|
|
/// <summary>
|
|
/// Provides access to Common endpoints.
|
|
/// </summary>
|
|
public CommonApi Common { get; }
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="ReCClient"/> class.
|
|
/// </summary>
|
|
/// <param name="httpClientFactory">The factory to create HttpClients.</param>
|
|
/// <param name="options">An optional set of client options. Defaults are used when omitted.</param>
|
|
/// <param name="logger">An optional logger used to record API call outcomes.</param>
|
|
#if NETFRAMEWORK
|
|
public ReCClient(IHttpClientFactory httpClientFactory, IOptions<ReCClientOptions> options = null, ILogger logger = null)
|
|
#else
|
|
public ReCClient(IHttpClientFactory httpClientFactory, IOptions<ReCClientOptions>? options = null, ILogger<ReCClient>? logger = null)
|
|
#endif
|
|
{
|
|
_http = httpClientFactory.CreateClient(ClientName);
|
|
var opts = options?.Value ?? new ReCClientOptions();
|
|
|
|
if (opts.LogSuccessfulRequests && logger == null)
|
|
throw new InvalidOperationException(
|
|
$"{nameof(ReCClientOptions.LogSuccessfulRequests)} is enabled, but no {nameof(ILogger)} was injected into {nameof(ReCClient)}. " +
|
|
$"Register a logging provider (e.g. services.AddLogging()) so that an {nameof(ILogger)} can be resolved, " +
|
|
$"or set {nameof(ReCClientOptions.LogSuccessfulRequests)} to false.");
|
|
|
|
RecActions = new RecActionApi(_http, logger, opts);
|
|
Results = new ResultApi(_http, logger, opts);
|
|
Profiles = new ProfileApi(_http, logger, opts);
|
|
EndpointAuth = new EndpointAuthApi(_http, logger, opts);
|
|
EndpointParams = new EndpointParamsApi(_http, logger, opts);
|
|
Endpoints = new EndpointsApi(_http, logger, opts);
|
|
Common = new CommonApi(_http, logger, opts);
|
|
}
|
|
|
|
#region Static
|
|
private static readonly IServiceCollection Services = new ServiceCollection();
|
|
|
|
#if NET8_0_OR_GREATER
|
|
private static IServiceProvider? Provider = null;
|
|
#else
|
|
private static IServiceProvider Provider = null;
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// Configures and builds the static <see cref="IServiceProvider"/> for creating <see cref="ReCClient"/> instances.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This method should only be called once during application startup.
|
|
/// </remarks>
|
|
/// <param name="apiUri">The base URI of the ReC API.</param>
|
|
/// <param name="configureOptions">An optional callback to configure <see cref="ReCClientOptions"/>.</param>
|
|
/// <exception cref="InvalidOperationException">Thrown if the static provider has already been built.</exception>
|
|
[Obsolete("Use a local service collection instead of the static provider.")]
|
|
#if NETFRAMEWORK
|
|
public static void BuildStaticClient(string apiUri, Action<ReCClientOptions> configureOptions = null)
|
|
#else
|
|
public static void BuildStaticClient(string apiUri, Action<ReCClientOptions>? configureOptions = null)
|
|
#endif
|
|
{
|
|
if(Provider != null)
|
|
throw new InvalidOperationException("Static Provider is already built.");
|
|
|
|
Services.AddRecClient(apiUri, configureOptions);
|
|
Provider = Services.BuildServiceProvider();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Configures and builds the static <see cref="IServiceProvider"/> for creating <see cref="ReCClient"/> instances.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This method should only be called once during application startup.
|
|
/// </remarks>
|
|
/// <param name="configureClient">An action to configure the <see cref="HttpClient"/>.</param>
|
|
/// <param name="configureOptions">An optional callback to configure <see cref="ReCClientOptions"/>.</param>
|
|
/// <exception cref="InvalidOperationException">Thrown if the static provider has already been built.</exception>
|
|
[Obsolete("Use a local service collection instead of the static provider.")]
|
|
#if NETFRAMEWORK
|
|
public static void BuildStaticClient(Action<HttpClient> configureClient, Action<ReCClientOptions> configureOptions = null)
|
|
#else
|
|
public static void BuildStaticClient(Action<HttpClient> configureClient, Action<ReCClientOptions>? configureOptions = null)
|
|
#endif
|
|
{
|
|
if (Provider != null)
|
|
throw new InvalidOperationException("Static Provider is already built.");
|
|
|
|
Services.AddRecClient(configureClient, configureOptions);
|
|
Provider = Services.BuildServiceProvider();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new <see cref="ReCClient"/> instance using the statically configured provider.
|
|
/// </summary>
|
|
/// <returns>A new instance of the <see cref="ReCClient"/>.</returns>
|
|
/// <exception cref="InvalidOperationException">Thrown if <see cref="BuildStaticClient(string)"/> has not been called yet.</exception>
|
|
[Obsolete("Use a local service collection instead of the static provider.")]
|
|
public static ReCClient Create()
|
|
{
|
|
if (Provider == null)
|
|
throw new InvalidOperationException("Static Provider is not built. Call BuildStaticClient first.");
|
|
|
|
return Provider.GetRequiredService<ReCClient>();
|
|
}
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Specifies which part of the result to return for result view endpoints.
|
|
/// </summary>
|
|
public enum ResultType
|
|
{
|
|
/// <summary>
|
|
/// Returns both header and body.
|
|
/// </summary>
|
|
Full,
|
|
/// <summary>
|
|
/// Returns only the header portion of the result.
|
|
/// </summary>
|
|
OnlyHeader,
|
|
/// <summary>
|
|
/// Returns only the body portion of the result.
|
|
/// </summary>
|
|
OnlyBody
|
|
}
|
|
} |