Open robertmclaws opened 3 years ago
AsyncLocal is basically impossible to use correctly without mentally (or on a whiteboard!) desugaring all async/await into a state machine to figure out what the “span” of an AsyncLocal value is.
I wrote an entire async locking library around AsyncLocal and it works great and is used by a lot of people but I am still not comfortable writing greenfield code w/ AsyncLocal, truth be told.
Is there some way of getting Roslyn to spit out the desugared C# (instead of reversing the IL to C#)?
Background and Motivation
On AspNetCore, when you need to access the
HttpContext
in a "service" class, you use anIHttpContextAccessor
to get the thread-safe instance of theHttpContext
used by the current thread, thanks to its internal use ofAsyncLocal
.However, if you need to be able to access the
HttpContext.User
, AND the service class is in another assembly, you can no longer rely onClaimsPrincipal.Current
orThread.CurrentPrincipal
to get you that information. If you control the external assembly, you're now dependent onMicrosoft.AspNetCore.Http
in all of your libraries, which is unnecessary.Proposed API
The proposal is a stand-alone class that does not affect the behavior or functionality of any existing APIs, which should make it quick to approve and get into the current release, even given the current timeframe for .NET 6's release.
The solution is to implement an identical pattern to
IHttpContextAccessor
forIPrincipal
. This will require an Interface to be added toSystem.Security
, and anHttpContextPrincipalAccessor
inMicrosoft.AspNetCore.Http
.Because the shipped implementation takes an
IHttpContextAccessor
in the constructor, it will pull in the thread'sHttpContext
to correctly pull the user from.Usage Examples
Alternative Designs
ClaimsPrincipal
, as that is the proper way to do things, but I considered that it could be aWindowsPrincipal
instead, soIPrincipal
is probably a better approach.TryAddService()
onIHttpContextAccessor
, just in case the user forgot to add one.Risks
IPrincipalAccessor
API would need to get in the .NET Core Libraries, which risks the team not wanting to add it at this stage of the game.HttpContextPrincipalAccessor
at this stage of the game, even if the .NET Core team is cool with it.I have the requisite pull requests ready to submit if the team is OK with this.