rebus-org / Rebus.ServiceProvider

:bus: Microsoft Extensions Dependency Injection container adapter for Rebus
https://mookid.dk/category/rebus
Other
65 stars 32 forks source link

UseRebus with async busAction results in unrecommended async void #44

Closed sorensenmatias closed 3 years ago

sorensenmatias commented 3 years ago

This piece of code, that I see is recommended, results in async void delegates:

app.ApplicationServices.UseRebus(async bus => await bus.Subscribe<Message1>())

The problem is that the busAction parameter is of type Action.

Analyzing with the analyzers from the NuGet package Microsoft.VisualStudio.Threading.Analyzers shows the issue: Warning VSTHRD101 Avoid using async lambda for a void returning delegate type, because any exceptions not handled by the delegate will crash the process. Read more here: https://github.com/Microsoft/vs-threading/blob/master/doc/analyzers/VSTHRD101.md

I believe it could be resolved by adding this extension method:

public static async Task<IServiceProvider> UseRebus(this IServiceProvider provider, Func<IBus, Task> busAction)

And then await the busAction inside the method. I do have a bit of doubt whether this is actually a good idea - async extension methods on IServiceProvider is not standard AFAIK. But I can submit a PR if desired.

mookid8000 commented 3 years ago

Well.... Rebus actually has a synchronous API, so one could just go

app.ApplicationServices.UseRebus(bus => bus.Advanced.SyncBus.Subscribe<Message1>());

and then everything would be dandy. But I think that your suggestion of changing the signature into Task<IServiceProvider> UseRebus(this IServiceProvider provider, Func<IBus, Task> busAction) makes the most sense, as it's more intuitive and less prone to be used wrong.

PR is most welcome 🙂

mookid8000 commented 3 years ago

Fixed in Rebus.ServiceProvider 6.3.0