Home > Blockchain >  Is there a way to scope lifetime in .NET DI to a thread, including child threads?
Is there a way to scope lifetime in .NET DI to a thread, including child threads?

Time:11-09

To enforce authorization in my applications, I usually decorate every domain service with an authorization decorator, that takes some service authorizer to perform authorization.

For instance: CarService : ICarService is decorated with CarServiceAuthorizationDecorator : ICarService that gets an ICarServiceAuthorizer injected to perform authorization and when successfull, calls the actual CarService.

This setup has served me well, except one little detail that has always bugged me: I have to pass some Token with every single call to ICarService, because the authorizer needs it. Even if it doesn't, then the CarService may call a CarOwnerShipService that is again decorated with an authorizer, that may need it as well. A lot of Tokens everywhere.

The only way that I can come up with, to fix this, is to inject some ITokenProvider into the CarServiceAuthorizer that acts like a storage device: You put in the token at the start, and it keeps it along the way for any service that gets it out, so it doesn't need to be passed with every method call.

For this to work, the lifetime of that ITokenProvider must be the same as the lifetime of the thread. And not only that: newly spawned threads will need the token too.

So my question is: Is there a way to scope the lifetime of my ITokenProvider to a thread, including child threads, in .NET DI?

(AddScoped doesn't seem to help me, I think, because not all threads in my application start with a web request. Also, I have had major issues with newly spawned threads with AddScoped, that would lose their state.)

CodePudding user response:

that acts like a storage device: You put in the token at the start, and it keeps it along the way for any service that gets it out, so it doesn't need to be passed with every method call.

AddScoped doesn't seem to help me, I think, because not all threads in my application start with a web request.

Based on the first quote I would argue that scoped ITokenProvider is exactly what you need (though without seeing the actual code it is more of a guess). Just create a scope when needed and use it, and do not rely on threading (i.e. you can spawn several threads using the same scope). Something along this lines:

IServiceProvider serviceProvider = ...;
using (var serviceScope = serviceProvider.CreateScope())
{
    var tokenService = serviceProvider.GetRequiredService<ITokenProvider>(); // or even split `ITokenProvider` into two interfaces
    tokenService.SetToken("");
    // resolve and call something using the token somewhere down the pipeline ...
    // Maybe even with Task.Run(...)
}
  • Related