using Elsa.Api.Client.Options; using Elsa.Api.Client.Resources.ActivityDescriptorOptions.Contracts; using Elsa.Api.Client.Resources.ActivityDescriptors.Contracts; using Elsa.Api.Client.Resources.ActivityExecutions.Contracts; using Elsa.Api.Client.Resources.Features.Contracts; using Elsa.Api.Client.Resources.Identity.Contracts; using Elsa.Api.Client.Resources.IncidentStrategies.Contracts; using Elsa.Api.Client.Resources.Scripting.Contracts; using Elsa.Api.Client.Resources.StorageDrivers.Contracts; using Elsa.Api.Client.Resources.Tasks.Contracts; using Elsa.Api.Client.Resources.VariableTypes.Contracts; using Elsa.Api.Client.Resources.WorkflowActivationStrategies.Contracts; using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts; using Elsa.Api.Client.Resources.WorkflowExecutionContexts.Contracts; using Elsa.Api.Client.Resources.WorkflowInstances.Contracts; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; using Refit; using static Elsa.Api.Client.RefitSettingsHelper; namespace Elsa.Api.Client.Extensions; /// Provides extension methods for dependency injection. [PublicAPI] public static class DependencyInjectionExtensions { /// Adds default Elsa API clients configured to use an API key. public static IServiceCollection AddDefaultApiClientsUsingApiKey(this IServiceCollection services, Action configureOptions) { var options = new ElsaClientOptions(); configureOptions(options); return services.AddDefaultApiClients(client => { client.BaseAddress = options.BaseAddress; client.ApiKey = options.ApiKey; client.ConfigureHttpClient = options.ConfigureHttpClient; }); } /// Adds default Elsa API clients. public static IServiceCollection AddDefaultApiClients(this IServiceCollection services, Action? configureClient = null) { return services.AddApiClients(configureClient, builderOptions => { var builderOptionsWithoutRetryPolicy = new ElsaClientBuilderOptions { ApiKey = builderOptions.ApiKey, AuthenticationHandler = builderOptions.AuthenticationHandler, BaseAddress = builderOptions.BaseAddress, ConfigureHttpClient = builderOptions.ConfigureHttpClient, ConfigureHttpClientBuilder = builderOptions.ConfigureHttpClientBuilder, ConfigureRetryPolicy = null }; services.AddApi(builderOptions); services.AddApi(builderOptionsWithoutRetryPolicy); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); services.AddApi(builderOptions); }); } /// /// Adds an API client to the service collection. Requires AddElsaClient to be called exactly once. /// public static IServiceCollection AddApiClient(this IServiceCollection services, Action? configureClient = null) where T : class { return services.AddApiClients(configureClient, builderOptions => services.AddApi(builderOptions)); } /// Adds the Elsa client to the service collection. public static IServiceCollection AddApiClients(this IServiceCollection services, Action? configureClient = null, Action? configureServices = null) { var builderOptions = new ElsaClientBuilderOptions(); configureClient?.Invoke(builderOptions); builderOptions.ConfigureHttpClientBuilder += builder => builder.AddHttpMessageHandler(sp => (DelegatingHandler)sp.GetRequiredService(builderOptions.AuthenticationHandler)); services.TryAddScoped(builderOptions.AuthenticationHandler); services.Configure(options => { options.BaseAddress = builderOptions.BaseAddress; options.ConfigureHttpClient = builderOptions.ConfigureHttpClient; options.ApiKey = builderOptions.ApiKey; }); configureServices?.Invoke(builderOptions); return services; } /// /// Adds a refit client for the specified API type. /// /// The service collection. /// An options object that can be used to configure the HTTP client builder. /// The type representing the API. public static IServiceCollection AddApi(this IServiceCollection services, ElsaClientBuilderOptions? httpClientBuilderOptions = default) where T : class { return services.AddApi(typeof(T), httpClientBuilderOptions); } /// /// Adds a refit client for the specified API type. /// /// The service collection. /// The type representing the API /// An options object that can be used to configure the HTTP client builder. public static IServiceCollection AddApi(this IServiceCollection services, Type apiType, ElsaClientBuilderOptions? httpClientBuilderOptions = default) { var builder = services.AddRefitClient(apiType, _ => CreateRefitSettings(), apiType.Name).ConfigureHttpClient(ConfigureElsaApiHttpClient); httpClientBuilderOptions?.ConfigureHttpClientBuilder(builder); httpClientBuilderOptions?.ConfigureRetryPolicy?.Invoke(builder); return services; } /// /// Adds a refit client for the specified API type. /// /// The service collection. /// An options object that can be used to configure the HTTP client builder. /// The type representing the API. public static void AddApiWithoutRetryPolicy(this IServiceCollection services, ElsaClientBuilderOptions? httpClientBuilderOptions = default) where T : class { var builder = services .AddRefitClient(_ => CreateRefitSettings(), typeof(T).Name) .ConfigureHttpClient(ConfigureElsaApiHttpClient); httpClientBuilderOptions?.ConfigureHttpClientBuilder(builder); } /// Creates an API client for the specified API type. public static T CreateApi(this IServiceProvider serviceProvider, Uri baseAddress) where T : class { var httpClientFactory = serviceProvider.GetRequiredService(); var httpClient = httpClientFactory.CreateClient(typeof(T).Name); httpClient.BaseAddress = baseAddress; return CreateApi(serviceProvider, httpClient); } /// Creates an API client for the specified API type. public static T CreateApi(this IServiceProvider serviceProvider, HttpClient httpClient) where T : class { return RestService.For(httpClient, CreateRefitSettings()); } private static void ConfigureElsaApiHttpClient(IServiceProvider serviceProvider, HttpClient httpClient) { var options = serviceProvider.GetRequiredService>().Value; httpClient.BaseAddress = options.BaseAddress; options.ConfigureHttpClient?.Invoke(serviceProvider, httpClient); } }