Search code examples
c#asp.net.net-6.0httpcontext

How to access HttpContext in mediatr command without installing deprecated nuget packages


I have a .NET 6 API and I want to get the HttpContext in a mediatr command, I have read on the docs it is possible to register the HttpContextAccessor with builder.Services.AddHttpContextAccessor(); which I did with no issues, but when I want to inject IHttpContextAccessor in the constructor of the command, my IDE tells it cannot resolve the symbol. I've looked on multiple other sources as well, they mostly point to either microsoft.aspnetcore.http or microsoft.aspnetcore.app to be installed. Sadly these nuget packages are deprecated, so I'm searching for a solution which doesn't use these.

PS: the api and mediatr commands are not in the same project

I've searched on multiple other sites to find an answer, but they either don't specify the package they are using, or they use a deprecated one.


Solution

  • To use ASP.NET Core 3+ types in non-web.sdk projects, use shared framework reference.

    Example project:

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <TargetFrameworks>net6.0</TargetFrameworks>
        <Nullable>enable</Nullable>
        <OutputType>Library</OutputType>
      </PropertyGroup>
    
      <ItemGroup>
        <FrameworkReference Include="Microsoft.AspNetCore.App" />
      </ItemGroup>
    
    </Project>
    

    However, note that this exists primarily to provide libraries with endpoints etc. Using this reference in business layer couples business logic with web API framework.

    A more flexible approach is to provide an interface for the needed capability in the business logic project and provide implementation in the API project.

    So for example

    // In business project
    public interface IMySpecialContext
    {
        string Value { get; }
    }
    
    // In API project
    public class HttpMySpecialContext : IMySpecialContext
    {
        private readonly IHttpContextAccessor _httpContextAccessor;
    
        public HttpMySpecialContext(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }
    
        public string Value
        {
            // Probably should throw for missing HttpContext or header.
            get => _httpContextAccessor.HttpContext?.Request.Headers["X-My-Special-Header"]!;
        }
    }
    
    // In unit tests
    public class DummyMySpecialContext : IMySpecialContext
    {
        public string Value => "Dummy Special Context Value";
    }