サービスを拡張メソッドに移動する
前回作成したプログラムでは、サービスを追加していくと Program.cs が、以下のようになっていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddDbContext<MvcAppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("MvcAppDb")) ); builder.Services.AddScoped<IAaaService, AaaImpl>(); builder.Services.AddScoped<IBbbService, BbbImpl>(); builder.Services.AddScoped<ICccService, CccImpl>(); : : var app = builder.Build(); ~ 以下略 ~ |
2~3個のサービスならこれでも良いかもしれませんが、50個、100個となった場合 Program.cs が長大になり、またサービスを追加する度に Program.cs を修正しなければならないため、メンテナンス性が悪くなってしまいます。
今回は、拡張メソッドを新規に作成して、Program.cs に登録していたサービスを拡張メソッドに移動させます。
拡張メソッドは、マイクロソフトの公式サイトによると、以下のような内容になります。
拡張メソッドを使用すると、新規の派生型の作成、再コンパイル、または元の型の変更を行うことなく既存の型にメソッドを "追加" できます。 拡張メソッドは静的メソッドですが、拡張された型のインスタンス メソッドのように呼び出します。
~ 以下略 ~
要するに、既存のクラスに対して、自作したメソッドを継承することなく追加することができる仕組みです。
拡張メソッドを使用したサービスのグループ化に関する詳しい内容は、以下のマイクロソフト公式サイトを参照してください。
サービスを登録するクラスを作成する
拡張メソッドを作成するにあたり、以下のルールがあります。
- クラスは、staticキーワードを使って静的クラスにする
- メソッドは、staticキーワードを使って静的メソッドにする
- メソッドの第一引数に、thisキーワードを付ける
クラスの配置場所は特に決まりはありません。
今回作成する拡張メソッドは、IServiceCollection の型を持ち、引数として IServiceCollection の型を受け取ります。
そして、この拡張メソッドの中に、サービスを随時追加していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
namespace 名前空間 { public static class クラス名 { public static IServiceCollection 拡張メソッド名(this IServiceCollection 引数名) { 引数名.AddScoped<インターフェイス名, メソッド名>(); 引数名.AddScoped<インターフェイス名, メソッド名>(); 引数名.AddScoped<インターフェイス名, メソッド名>(); : return services; } } } |
また、Program.cs で呼び出す時に、戻りを受け取らない場合は、拡張メソッドをvoid型で作成しても問題ありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
namespace 名前空間 { public static class クラス名 { public static void 拡張メソッド名(this IServiceCollection 引数名) { 引数名.AddScoped<インターフェイス名, メソッド名>(); 引数名.AddScoped<インターフェイス名, メソッド名>(); 引数名.AddScoped<インターフェイス名, メソッド名>(); : } } } |
上記の例ではサービスをスコープ付き有効期間で登録する AddScoped()メソッドを使用していますが、他にも AddTransient()メソッドや AddSingleton()メソッドがあります。
有効期間に関する詳しい内容は、以下のマイクロソフト公式サイトを参照してください。
Program.csにグループ化したサービスを登録する
Program.cs 内に作成した拡張メソッド登録します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using Microsoft.EntityFrameworkCore; using MvcApp3.Data; using MvcApp3.Services; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddDbContext<MvcAppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("MvcAppDb")) ); builder.Services.拡張メソッド名; var app = builder.Build(); ~ 以下略 ~ |
拡張メソッドを作成することで、これ以降 Program.cs を修正することなく、サービスを追加することができるようになります。