diff --git a/src/Dapr.Workflow/DaprWorkflowClientBuilderFactory.cs b/src/Dapr.Workflow/DaprWorkflowClientBuilderFactory.cs index 8e284baf3..760dadd8b 100644 --- a/src/Dapr.Workflow/DaprWorkflowClientBuilderFactory.cs +++ b/src/Dapr.Workflow/DaprWorkflowClientBuilderFactory.cs @@ -19,8 +19,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -#nullable enable - namespace Dapr.Workflow; /// @@ -28,35 +26,33 @@ namespace Dapr.Workflow; /// internal sealed class DaprWorkflowClientBuilderFactory { - private readonly IConfiguration _configuration; - private readonly IHttpClientFactory _httpClientFactory; - private readonly IServiceCollection _services; + private readonly IConfiguration? configuration; + private readonly IHttpClientFactory httpClientFactory; /// /// Constructor used to inject the required types into the factory. /// - public DaprWorkflowClientBuilderFactory(IConfiguration configuration, IHttpClientFactory httpClientFactory, IServiceCollection services) + public DaprWorkflowClientBuilderFactory(IConfiguration? configuration, IHttpClientFactory httpClientFactory) { - _configuration = configuration; - _httpClientFactory = httpClientFactory; - _services = services; + this.configuration = configuration; + this.httpClientFactory = httpClientFactory; } /// /// Responsible for building the client itself. /// /// - public void CreateClientBuilder(Action configure) + public void CreateClientBuilder(IServiceCollection services, Action configure) { - _services.AddDurableTaskClient(builder => + services.AddDurableTaskClient(builder => { WorkflowRuntimeOptions options = new(); - configure?.Invoke(options); + configure.Invoke(options); - var apiToken = DaprDefaults.GetDefaultDaprApiToken(_configuration); - var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(_configuration); + var apiToken = DaprDefaults.GetDefaultDaprApiToken(configuration); + var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(configuration); - var httpClient = _httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(); if (!string.IsNullOrWhiteSpace(apiToken)) { @@ -72,17 +68,17 @@ public void CreateClientBuilder(Action configure) builder.RegisterDirectly(); }); - _services.AddDurableTaskWorker(builder => + services.AddDurableTaskWorker(builder => { WorkflowRuntimeOptions options = new(); - configure?.Invoke(options); + configure.Invoke(options); - var apiToken = DaprDefaults.GetDefaultDaprApiToken(_configuration); - var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(_configuration); + var apiToken = DaprDefaults.GetDefaultDaprApiToken(configuration); + var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(configuration); if (!string.IsNullOrEmpty(grpcEndpoint)) { - var httpClient = _httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(); if (!string.IsNullOrWhiteSpace(apiToken)) { diff --git a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs index 3c19583aa..5c10a776e 100644 --- a/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs +++ b/src/Dapr.Workflow/WorkflowServiceCollectionExtensions.cs @@ -11,51 +11,55 @@ // limitations under the License. // ------------------------------------------------------------------------ -namespace Dapr.Workflow -{ - using System; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.DependencyInjection.Extensions; +using System; +using System.Net.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Dapr.Workflow; +/// +/// Contains extension methods for using Dapr Workflow with dependency injection. +/// +public static class WorkflowServiceCollectionExtensions +{ /// - /// Contains extension methods for using Dapr Workflow with dependency injection. + /// Adds Dapr Workflow support to the service collection. /// - public static class WorkflowServiceCollectionExtensions + /// The . + /// A delegate used to configure actor options and register workflow functions. + public static IServiceCollection AddDaprWorkflow( + this IServiceCollection serviceCollection, + Action configure) { - /// - /// Adds Dapr Workflow support to the service collection. - /// - /// The . - /// A delegate used to configure actor options and register workflow functions. - public static IServiceCollection AddDaprWorkflow( - this IServiceCollection serviceCollection, - Action configure) + if (serviceCollection == null) { - if (serviceCollection == null) - { - throw new ArgumentNullException(nameof(serviceCollection)); - } + throw new ArgumentNullException(nameof(serviceCollection)); + } - serviceCollection.TryAddSingleton(); - serviceCollection.AddHttpClient(); + serviceCollection.TryAddSingleton(); + serviceCollection.AddHttpClient(); #pragma warning disable CS0618 // Type or member is obsolete - keeping around temporarily - replaced by DaprWorkflowClient - serviceCollection.TryAddSingleton(); + serviceCollection.TryAddSingleton(); #pragma warning restore CS0618 // Type or member is obsolete - serviceCollection.AddHostedService(); - serviceCollection.TryAddSingleton(); - serviceCollection.AddDaprClient(); + serviceCollection.AddHostedService(); + serviceCollection.TryAddSingleton(); + serviceCollection.AddDaprClient(); - serviceCollection.AddOptions().Configure(configure); - - serviceCollection.AddSingleton(c => - { - var factory = c.GetRequiredService(); - factory.CreateClientBuilder(configure); - return new object(); //Placeholder as actual registration is performed inside factory - }); - - return serviceCollection; + serviceCollection.AddOptions().Configure(configure); + + //Register the factory and force resolution so the Durable Task client and worker can be registered + using (var scope = serviceCollection.BuildServiceProvider().CreateScope()) + { + var httpClientFactory = scope.ServiceProvider.GetRequiredService(); + var configuration = scope.ServiceProvider.GetService(); + + var factory = new DaprWorkflowClientBuilderFactory(configuration, httpClientFactory); + factory.CreateClientBuilder(serviceCollection, configure); } + + return serviceCollection; } }