Skip to content

ASP.NET Core integration: missing IHostedService support and async handler interface #4

@gimmickj

Description

@gimmickj

Hi, thanks for providing the .NET client. I've been trying to integrate it into an ASP.NET Core application and ran into two issues that make it difficult to use in a production hosted environment.

Problem 1: No IHostedService / BackgroundService integration

The current design assumes a console application entry point:

var subscription = externalWorkerClient.Subscribe("myTopic", new HandleJobs());
Console.ReadLine(); // blocks main thread

In ASP.NET Core, the standard pattern for background processing is BackgroundService. There's no built-in way to plug ExternalWorkerClient into the hosted service lifecycle, which means developers have to write their own wrapper just to get basic integration working.

It would be great to have something like:

services.AddFlowableExternalWorker(options =>
{
    options.Host = "http://localhost:8090/flowable-work";
})
.AddWorker<HandleJobs>("myTopic");

Where HandleJobs is resolved from the DI container and the polling is managed by a BackgroundService that respects IHostApplicationLifetime.

Problem 2: IExternalWorkerCallbackHandler is synchronous

The handler interface only supports synchronous execution:

public interface IExternalWorkerCallbackHandler
{
    IWorkResult Handle(ExternalWorkerAcquireJobResponse job, IWorkResultBuilder work);
}

In ASP.NET Core applications, business logic is almost always async (database calls, HTTP calls, etc.). This forces developers to block on async code:

public IWorkResult Handle(ExternalWorkerAcquireJobResponse job, IWorkResultBuilder work)
{
    // This is a known anti-pattern in ASP.NET Core and can cause deadlocks
    var result = myService.DoWorkAsync(job).GetAwaiter().GetResult();
    return work.Success();
}

An async version of the interface would solve this:

public interface IExternalWorkerCallbackHandler
{
    Task<IWorkResult> HandleAsync(ExternalWorkerAcquireJobResponse job, IWorkResultBuilder work, CancellationToken cancellationToken);
}

Problem 3: No DI support for handlers

Because handlers are instantiated manually (new HandleJobs()), there's no way to inject scoped services like a database context or a mediator. A proper DI-aware design would resolve the handler from IServiceScopeFactory per job execution, similar to how ASP.NET Core resolves scoped services per request.

Suggested improvement

A Microsoft.Extensions.Hosting integration package (e.g. Flowable.ExternalWorkerClient.Hosting) similar to what other libraries provide would make this library production-ready for ASP.NET Core. The Java client has good Spring Boot integration as a reference point.

Thanks for considering this.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions