Fix for DI registration not completing as expected (#1386)

* Tentative fix for DI registration not completing as expected

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Making injected IConfiguration optional as it might not be populated if user isn't utilizing ASP.NET Core from caller

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed DI injection issue

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Removed registration of DaprWorkflowClientBuilderFactory

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Updated field names for consistency

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Minor formatting changes

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

* Fixed build error caused by bad merge resolution

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
This commit is contained in:
Whit Waldo 2024-11-05 01:28:02 -06:00 committed by GitHub
parent e7d3c47615
commit 682df6fec9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 55 deletions

View File

@ -19,8 +19,6 @@ using Microsoft.DurableTask.Worker;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
#nullable enable
namespace Dapr.Workflow; namespace Dapr.Workflow;
/// <summary> /// <summary>
@ -28,35 +26,33 @@ namespace Dapr.Workflow;
/// </summary> /// </summary>
internal sealed class DaprWorkflowClientBuilderFactory internal sealed class DaprWorkflowClientBuilderFactory
{ {
private readonly IConfiguration _configuration; private readonly IConfiguration? configuration;
private readonly IHttpClientFactory _httpClientFactory; private readonly IHttpClientFactory httpClientFactory;
private readonly IServiceCollection _services;
/// <summary> /// <summary>
/// Constructor used to inject the required types into the factory. /// Constructor used to inject the required types into the factory.
/// </summary> /// </summary>
public DaprWorkflowClientBuilderFactory(IConfiguration configuration, IHttpClientFactory httpClientFactory, IServiceCollection services) public DaprWorkflowClientBuilderFactory(IConfiguration? configuration, IHttpClientFactory httpClientFactory)
{ {
_configuration = configuration; this.configuration = configuration;
_httpClientFactory = httpClientFactory; this.httpClientFactory = httpClientFactory;
_services = services;
} }
/// <summary> /// <summary>
/// Responsible for building the client itself. /// Responsible for building the client itself.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public void CreateClientBuilder(Action<WorkflowRuntimeOptions> configure) public void CreateClientBuilder(IServiceCollection services, Action<WorkflowRuntimeOptions> configure)
{ {
_services.AddDurableTaskClient(builder => services.AddDurableTaskClient(builder =>
{ {
WorkflowRuntimeOptions options = new(); WorkflowRuntimeOptions options = new();
configure?.Invoke(options); configure.Invoke(options);
var apiToken = DaprDefaults.GetDefaultDaprApiToken(_configuration); var apiToken = DaprDefaults.GetDefaultDaprApiToken(configuration);
var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(_configuration); var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(configuration);
var httpClient = _httpClientFactory.CreateClient(); var httpClient = httpClientFactory.CreateClient();
if (!string.IsNullOrWhiteSpace(apiToken)) if (!string.IsNullOrWhiteSpace(apiToken))
{ {
@ -72,17 +68,17 @@ internal sealed class DaprWorkflowClientBuilderFactory
builder.RegisterDirectly(); builder.RegisterDirectly();
}); });
_services.AddDurableTaskWorker(builder => services.AddDurableTaskWorker(builder =>
{ {
WorkflowRuntimeOptions options = new(); WorkflowRuntimeOptions options = new();
configure?.Invoke(options); configure.Invoke(options);
var apiToken = DaprDefaults.GetDefaultDaprApiToken(_configuration); var apiToken = DaprDefaults.GetDefaultDaprApiToken(configuration);
var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(_configuration); var grpcEndpoint = DaprDefaults.GetDefaultGrpcEndpoint(configuration);
if (!string.IsNullOrEmpty(grpcEndpoint)) if (!string.IsNullOrEmpty(grpcEndpoint))
{ {
var httpClient = _httpClientFactory.CreateClient(); var httpClient = httpClientFactory.CreateClient();
if (!string.IsNullOrWhiteSpace(apiToken)) if (!string.IsNullOrWhiteSpace(apiToken))
{ {

View File

@ -11,51 +11,55 @@
// limitations under the License. // limitations under the License.
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
namespace Dapr.Workflow using System;
using System.Net.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Dapr.Workflow;
/// <summary>
/// Contains extension methods for using Dapr Workflow with dependency injection.
/// </summary>
public static class WorkflowServiceCollectionExtensions
{ {
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
/// <summary> /// <summary>
/// Contains extension methods for using Dapr Workflow with dependency injection. /// Adds Dapr Workflow support to the service collection.
/// </summary> /// </summary>
public static class WorkflowServiceCollectionExtensions /// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param>
/// <param name="configure">A delegate used to configure actor options and register workflow functions.</param>
public static IServiceCollection AddDaprWorkflow(
this IServiceCollection serviceCollection,
Action<WorkflowRuntimeOptions> configure)
{ {
/// <summary> if (serviceCollection == null)
/// Adds Dapr Workflow support to the service collection.
/// </summary>
/// <param name="serviceCollection">The <see cref="IServiceCollection"/>.</param>
/// <param name="configure">A delegate used to configure actor options and register workflow functions.</param>
public static IServiceCollection AddDaprWorkflow(
this IServiceCollection serviceCollection,
Action<WorkflowRuntimeOptions> configure)
{ {
if (serviceCollection == null) throw new ArgumentNullException(nameof(serviceCollection));
{ }
throw new ArgumentNullException(nameof(serviceCollection));
}
serviceCollection.TryAddSingleton<WorkflowRuntimeOptions>(); serviceCollection.TryAddSingleton<WorkflowRuntimeOptions>();
serviceCollection.AddHttpClient(); serviceCollection.AddHttpClient();
#pragma warning disable CS0618 // Type or member is obsolete - keeping around temporarily - replaced by DaprWorkflowClient #pragma warning disable CS0618 // Type or member is obsolete - keeping around temporarily - replaced by DaprWorkflowClient
serviceCollection.TryAddSingleton<WorkflowEngineClient>(); serviceCollection.TryAddSingleton<WorkflowEngineClient>();
#pragma warning restore CS0618 // Type or member is obsolete #pragma warning restore CS0618 // Type or member is obsolete
serviceCollection.AddHostedService<WorkflowLoggingService>(); serviceCollection.AddHostedService<WorkflowLoggingService>();
serviceCollection.TryAddSingleton<DaprWorkflowClient>(); serviceCollection.TryAddSingleton<DaprWorkflowClient>();
serviceCollection.AddDaprClient(); serviceCollection.AddDaprClient();
serviceCollection.AddOptions<WorkflowRuntimeOptions>().Configure(configure); serviceCollection.AddOptions<WorkflowRuntimeOptions>().Configure(configure);
serviceCollection.AddSingleton(c => //Register the factory and force resolution so the Durable Task client and worker can be registered
{ using (var scope = serviceCollection.BuildServiceProvider().CreateScope())
var factory = c.GetRequiredService<DaprWorkflowClientBuilderFactory>(); {
factory.CreateClientBuilder(configure); var httpClientFactory = scope.ServiceProvider.GetRequiredService<IHttpClientFactory>();
return new object(); //Placeholder as actual registration is performed inside factory var configuration = scope.ServiceProvider.GetService<IConfiguration>();
});
var factory = new DaprWorkflowClientBuilderFactory(configuration, httpClientFactory);
return serviceCollection; factory.CreateClientBuilder(serviceCollection, configure);
} }
return serviceCollection;
} }
} }