NSB 7 + Autofac + TransactionalSession - A delegate registered to create instances of 'NServiceBus.Persistence.SynchronizedStorageSession' returned null

Hi there,

Using this example for transactional session (transactional session 6 and the example for .NET 6):

Everything works fine, but we use Autofac, so I added the appropriate line

    var host = Host.CreateDefaultBuilder()
       **.UseServiceProviderFactory(new AutofacServiceProviderFactory())**
        .UseNServiceBus(context =>

and everything still works fine - except if I call one of the apis that doesn’t take TransactionalSession as a param.

So if I hit this:

public async Task<string> Get([FromServices] ITransactionalSession messageSession)
{
    var id = Guid.NewGuid().ToString();

	...
	...
}

Its fine, it gets a transactional session.

If I hit this:
[HttpGet(“/all”)]
public async Task<List> GetAll()
{
return await dataContext.MyEntities.ToListAsync();
}

Then when it goes off to ask for the SynchronizedStorageSession via this line:

var synchronizedStorageSession = b.GetService();

It blows up with

Autofac.Core.DependencyResolutionException
  HResult=0x80131500
  Message=An exception was thrown while activating λ:NServiceBus.Persistence.SynchronizedStorageSession.
  Source=Autofac
  StackTrace:
   at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Middleware.SharingMiddleware.<>c__DisplayClass5_0.<Execute>b__0()
   at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid id, Func`1 creator)
   at Autofac.Core.Lifetime.LifetimeScope.CreateSharedInstance(Guid primaryId, Nullable`1 qualifyingId, Func`1 creator)
   at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest& request)
   at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest& request)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
   at Autofac.ResolutionExtensions.ResolveOptionalService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Program.<>c.<Main>b__1_4(IServiceProvider b) in C:\RolGit\aspnetcore-webapi_sqlpersistencets_6_net6_0\WebApplication\Program.cs:line 57
   at Autofac.Core.Activators.Delegate.DelegateActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Activators.Delegate.DelegateActivator.<ConfigurePipeline>b__2_0(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
   at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
DependencyResolutionException: A delegate registered to create instances of 'NServiceBus.Persistence.SynchronizedStorageSession' returned null.

and this does not happen when not using Autofac - the request for the service returns null in this scenario. Am I missing something?

Thanks for the detailed bug report @Rawk

I can reproduce this locally and will let you know when we have figured out the root cause.

Cheers,

Andreas

Some updates on this:

Samples for v7 and v8 of NServiceBus.Persistence.Sql.TransactionalSession work as expected with Autofac in use and it seems like the way v6 registers the storage session causes Autfac to throw when it’s not available, unlike the default MS container.

We’ll keep on digging.

In the meantime would using v7 or v8 be an option?

We will eventually go up - but v7 of NServiceBus.Persistence.Sql.TransactionalSession needs v8 of NSB, and we aren’t quite ready to bounce up to that yet.

Seems like we are hitting this Autofac issue

It’s closed as won’t fix so we are not sure if we are able to work around this in any other way than doing a try catch when trying to resolve the storage session.

I’ll let you know as soon as we have more details.

Cheers,

Andreas

Hi Robert,

It doesn’t look like we can workaround the Autofac behaviour easily in the v7 compatible version, what is the impact on your project not utilising the transactional session?

Would it be possible to migrate to another DI container or upgrade the affected endpoints to NServiceBus v8?

Cheers,

Andreas