Ninject InThreadScope() resolves a new class instance despite running on the same thread

74 Views Asked by At

At my job we have an ASP.NET MVC (.NET 4.6.2) system that uses a class called TenantService to carry tenant data around. We use Ninject to inject a reference to this class' interface into other classes.

We have a Quartz job which also receives the ITenantService injection into it's constructor. Right at the beginning of the Execute method of that job, we provide the tenant ID to the TenantService. After that, the job sends a MediatR command.

private readonly ITenantService _tenantService;

public SubmitSubmissionJob(ITenantService tenantService)
{
    _tenantService = tenantService;
}

public async Task Execute(IJobExecutionContext jobExecutionContext)
{
   (...)

   _tenantService.SetTenant(clientId);

   (...)

   _commandBus.SendCommand(new SubmitApplication(applicationId));

   (...)
}

MediatR redirects this command to an aggregate handler, which also receives an injection of the ITenantService into it's constructor:

private readonly ITenantService _tenantService;

public AggregateCommandHandlerBase(ITenantService tenantService)
{
    _tenantService = tenantService;
}

The problem is that the TenantService instance resolved inside the AggregateCommandHandlerBase is different to the one resolved inside the SubmitSubmissionJob, despite all of this code running on the same thread.

enter image description here

We bind the TenantService in NinjectWebCommon this way:

kernel.Bind<ITenantService>().To<TenantService>().InScope(x =>
{
   return (HttpContext.Current != null ? (object)HttpContext.Current : (object)Thread.CurrentThread);
});

but we also tried this:

kernel.Bind<ITenantService>().To<TenantService>().When(x => HttpContext.Current != null).InRequestScope();
kernel.Bind<ITenantService>().To<TenantService>().When(x => HttpContext.Current == null).InThreadScope();

Both bindings result in the same behaviour - the TenantService resolved inside the code AggregateCommandHandlerBase is a different instance to the one resolved inside the job, which causes the tenant data to not be passed further down the line.

We've been spinning our wheels on this for hours and can't figure out why the instances are different. Any help or pointers will be greatly appreciated!

0

There are 0 best solutions below