How to inject IPrincipal into a class

697 Views Asked by At

I have a class where I need to access IPrincipal because I will save some user information in a database from that class.

To inject it, I added this in Program.cs file:

builder.Services.AddScoped<IPrincipal>(
    (sp) => sp.GetService<IHttpContextAccessor>().HttpContext.User
);

With that, I receive a warning about IHttpContextAccessor telling that I need to use it with caution because it relies on AsyncLocal, and second, other warnings are shown telling I need to dereference GetService and HttpContext.

How can I do that properly in .NET Core 6?

enter image description here

1

There are 1 best solutions below

1
Guru Stron On BEST ANSWER

I receive a warning ... telling that I need to use it with caution because it relies

No, it is not the warning which is telling that, the caution comes from the remarks in the interface documentation which you see when you mouse over the interface definition.

The warning you are getting is about dereferencing of a possibly null reference (some docs).

warning CS8602: Dereference of a possibly null reference.

The issue is that GetService can return null, and IHttpContextAccessor.HttpContext can be null also which is caught by compiler (see nullable references types). The proper workaround would be to extract corresonding abstraction and register/resolve it:

public interface IPrincipalProvider
{
    IPrincipal? Principal { get; }
}

public class PrincipalProvider : IPrincipalProvider
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public PrincipalProvider(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public IPrincipal? Principal => _httpContextAccessor.HttpContext?.User;
}

builder.Services.AddScoped<IPrincipalProvider, PrincipalProvider>();