コントローラ以外でHttpContextを使いたい(ASP.NET CORE 6 MVC)

概要

ASP.NET COREでは、static HttpContextからSessionやIdentity.Userが取得できなくなったため、HttpContextAccessorを使用してSessionやIdentity.Userを取得するようにします。

取得方法

Program.csで、AddHttpContextAccessor()を呼び出すことで、HttpContextAccessorを各クラスへDIできるようにします。

Program.cs(抜粋)

var builder = WebApplication.CreateBuilder(args);

・・・ (省略)

builder.Services.AddHttpContextAccessor();

・・・ (省略)

HttpContextAccessorを参照するクラスは、DIによりクラスのコンストラクターの引数でHttpContextAccessorを受け取ります(ServiceProvider.GetServiceするためにはHttpContextが必要なためHttpContextAccessorを取得するにはDIにより取得するしかない)。
よって、HttpcontextAccessorを参照するクラスは、コントローラーやカスタムタグヘルパーやViewなどのDIの起点となるクラス、またはDIの起点となるクラスにDIされるクラスにDIされるクラスである必要があります。
なにいっているかわかんないですよね。DIは入れ子になってチェインされていきます。図にするとこんな感じです。

上記の例だと、.NET COREフレームワークは以下の手順でコントローラ「AController」のインスタンスを生成します。

  • Program.csでセットアップしたIHttpContextAccessorをServiceProviderから取得します。
  • IHttpContextAccessorをDIしてDUtilをnewします。
  • DUtilをDIしてCServiceをnewします。
  • CServiceをDIしてBServiceをnewします。
  • BServiceをDIしてAControllerをnewします。

実際のDUtilでは以下のようにHttpContextを使用します。

    public class DUtil
    {
        IHttpContextAccessor _Accessor;

        public DUtil(IHttpContextAccessor accessor)
        {
            _Accessor = accessor;
        }

        public string GetUser()
        {
            return _Accessor.HttpContext.User.Identity.Name;
        }