コンストラクタで順番など関係なしにパラメータを記述するだけで、オブジェクトがコンストラクタに渡されて動作してしまう - C#

コンストラクタで順番など関係なしにパラメータを記述するだけで、オブジェクトがコンストラクタに渡されて動作してしまうコードについて紹介します。

具体例

よくある例として、RazorPageのページオブジェクトの例があります。
RazorPageのページオブジェクトのコンストラクタは通常は引数(パラメータ)はありません。
RazorPage のページモデルのクラス例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace SimpleBlazorPages.Pages
{
  public class TestModel : PageModel
  {
    public TestModel()
    {
    }

    public void OnGet()
    {
    }
  }
}

ただし、同じコードを以下のコードに変更しても、コンパイルが通ります。
さらに実行すると、コンストラクタに渡される、configuration オブジェクトに設定情報が入った状態で渡されます。
RazorPage のページモデルのクラス例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;

namespace SimpleBlazorPages.Pages
{
  public class TestModel : PageModel
  {
    private IConfiguration _conf;
    public TestModel(IConfiguration configuration)
    {
      _conf = configuration;
    }

    public void OnGet()
    {
    }
  }
}

コンパイルが通ることも疑問ですし、実行したときに、オブジェクトが渡される挙動もよくわからないです。
さらに次のようにコードを変更してもコンパイルが通り、IConfiguration と IWebHostEnvironmentに情報が入ったオブジェクトが渡されます。
RazorPage のページモデルのクラス例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;

namespace SimpleBlazorPages.Pages
{
  public class TestModel : PageModel
  {
    private IConfiguration _conf;.
    private IWebHostEnvironment _env;

    public TestModel(IConfiguration configuration, IWebHostEnvironment env)
    {
      _conf = configuration;
      _env = env;
    }

    public void OnGet()
    {
    }
  }
}

動作する理由

RazorPagesのページモデルクラスは、DI(Dependency Injection) の仕組みでインスタンス化されるため、 コンストラクタの引数に自由に注入されるサービスクラスを記述できます。
DI(Dependency Injection)でのインスタンスの生成やコンストラクターのパラメータが可変になる詳細のサンプルは こちらの記事を参照して下さい。

補足

従来のC#のコードになじみがある場合、コンパイルが通ることに違和感を覚え、さらにどういう仕組みでオブジェクトが渡されるのかが理解できず、 非常に気持ち悪いコードに感じられます。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2021-09-25
iPentec all rights reserverd.