rebus-org / Rebus.ServiceProvider

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

Support AsyncServiceScope when handling messages #76

Closed francescodente closed 1 year ago

francescodente commented 1 year ago

With the introduction of .NET 6, the IServiceProvider got a new extension method (CreateAsyncScope()) that enables service scopes to be disposed using the IAsyncDisposable interface.

It would be nice if Rebus used this feature in the DependencyInjectionHandlerActivator to allow services that only implement IAsyncDispoable to be released as well.

For now, we were able to circumvent this by adding an incoming step at the front of the pipeline that mimics the implementation of the AsyncServiceScope.DisposeAsync() method by doing the following:

public class ServiceScopeAsyncDisposeStep : IIncomingStep
{
    public async Task Process(IncomingStepContext context, Func<Task> next)
    {
        await next();
        var scope = context.Load<IServiceScope>();
        if (scope is IAsyncDisposable asyncScope)
        {
            await asyncScope.DisposeAsync();
        }
    }
}
mookid8000 commented 1 year ago

I've just pushed Rebus.ServiceProvider 9.0.0-b01 to NuGet.org with support for async disposables! 🙂

Try it and see if it works! I'll release a proper version once I get some feedback on it.

arielmoraes commented 1 year ago

@mookid8000 I know the major was bumped to 9.0.0, but we had a breaking change in our code because of that change.

As we need set some instances in the scope before the handlers activation we had to create our own scope step, but as we were using the IServiceScope it got lost when activating the handlers.

I suggest splitting the scope creation and the handler activation, by doing that we can decorate the IPipeline by adding steps after the Scope Step so that the default order would be: Scope Creation Step -> ActivateHandlersStep. Then instead of creating a custom step, we could do Scope Creation Step -> My Custom Step -> ActivateHandlersStep.

mookid8000 commented 1 year ago

@arielmoraes I just went and took a look and made some adjustments - I think Rebus.ServiceProvider 10.0.0-alpha02 (which is on NuGet.org now) supports async scopes (like it should) as well as user-provided sync or async scopes.

Could you try and see if it works for you?

(closing this issue, because I think async scopes are supported now 🙂 ..)

EraYaN commented 1 year ago

I just tested this (with the Sync Scope) with the new alpha and it seems to work, it does in fact use our IServiceScope correctly, so we'll stick to 8.4.0 of this package until Rebus 8 is released.