using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Net.Http;
namespace ReC.Client
{
///
/// Static convenience entry-point for building and resolving a without an
/// externally provided . Intended for legacy scenarios (e.g. .NET Framework
/// codebases without an established DI container). For new code, prefer
/// .
///
public partial class ReCClient
{
#if NET8_0_OR_GREATER
private static Action? _staticConfigure = null;
#else
private static Action _staticConfigure = null;
#endif
private static readonly Lazy LazyProvider = new Lazy(() =>
{
var configure = _staticConfigure
?? throw new InvalidOperationException("Static Provider is not built. Call BuildStaticClient first.");
var services = new ServiceCollection();
configure(services);
return services.BuildServiceProvider();
}, System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
///
/// Configures and builds the static for creating instances.
///
///
/// This method should only be called once during application startup. The underlying
/// is created lazily and thread-safely on first access via .
///
/// Callback that populates a instance.
/// Thrown when is null.
/// Thrown when neither nor is set, when both are set, or when the static provider has already been built.
[Obsolete("Use a local service collection instead of the static provider.")]
public static void BuildStaticClient(Action configure)
{
if (configure == null)
throw new ArgumentNullException(nameof(configure));
var cfg = new StaticBuildConfiguration();
configure(cfg);
var hasBaseAddress = !string.IsNullOrWhiteSpace(cfg.BaseAddress);
var hasConfigureClient = cfg.ConfigureClient != null;
if (!hasBaseAddress && !hasConfigureClient)
throw new InvalidOperationException(
$"Either {nameof(StaticBuildConfiguration.BaseAddress)} or {nameof(StaticBuildConfiguration.ConfigureClient)} must be set on {nameof(StaticBuildConfiguration)}.");
if (hasBaseAddress && hasConfigureClient)
throw new InvalidOperationException(
$"{nameof(StaticBuildConfiguration.BaseAddress)} and {nameof(StaticBuildConfiguration.ConfigureClient)} are mutually exclusive on {nameof(StaticBuildConfiguration)}.");
Action register = services =>
{
if (hasBaseAddress)
services.AddRecClient(cfg.BaseAddress, cfg.ConfigureOptions);
else
services.AddRecClient(cfg.ConfigureClient, cfg.ConfigureOptions);
if (cfg.Logger != null)
services.AddSingleton(cfg.Logger);
cfg.ConfigureServices?.Invoke(services);
};
if (System.Threading.Interlocked.CompareExchange(ref _staticConfigure, register, null) != null)
throw new InvalidOperationException("Static Provider is already built.");
}
///
/// Configures and builds the static for creating instances.
///
///
/// This method should only be called once during application startup.
/// The underlying is created lazily and thread-safely on first access via .
///
/// The base URI of the ReC API.
/// An optional callback to configure .
/// An optional instance to be used by the . When provided, it is registered as a singleton in the internal service collection.
/// Thrown if the static provider has already been built.
[Obsolete("Use BuildStaticClient(Action) instead.")]
#if NETFRAMEWORK
public static void BuildStaticClient(string apiUri, Action configureOptions = null, ILogger logger = null)
#else
public static void BuildStaticClient(string apiUri, Action? configureOptions = null, ILogger? logger = null)
#endif
{
BuildStaticClient(cfg =>
{
cfg.BaseAddress = apiUri;
cfg.ConfigureOptions = configureOptions;
cfg.Logger = logger;
});
}
///
/// Configures and builds the static for creating instances.
///
///
/// This method should only be called once during application startup.
/// The underlying is created lazily and thread-safely on first access via .
///
/// An action to configure the .
/// An optional callback to configure .
/// An optional instance to be used by the . When provided, it is registered as a singleton in the internal service collection.
/// Thrown if the static provider has already been built.
[Obsolete("Use BuildStaticClient(Action) instead.")]
#if NETFRAMEWORK
public static void BuildStaticClient(Action configureClient, Action configureOptions = null, ILogger logger = null)
#else
public static void BuildStaticClient(Action configureClient, Action? configureOptions = null, ILogger? logger = null)
#endif
{
BuildStaticClient(cfg =>
{
cfg.ConfigureClient = configureClient;
cfg.ConfigureOptions = configureOptions;
cfg.Logger = logger;
});
}
///
/// Creates a new instance using the statically configured provider.
///
/// A new instance of the .
/// Thrown if has not been called yet.
[Obsolete("Use a local service collection instead of the static provider.")]
public static ReCClient Create()
{
return LazyProvider.Value.GetRequiredService();
}
}
}