BlazorのDI(依存性注入)とは?サービスの登録と使い方入門|ASP.NET×Blazor入門 8.1
8.1 DIの基本と登録方法(builder.Services.Add...)
Blazorでは、ASP.NET Coreと同様に依存性注入(Dependency Injection:DI)の仕組みが組み込まれており、 サービス(ビジネスロジックや状態管理クラスなど)をコンポーネントや他のサービスに自動的に渡すことができます。 DIを正しく活用することで、疎結合でテストしやすいコードが書けるようになり、アプリケーションのメンテナンス性が大きく向上します。
依存性注入とは?
依存性注入とは、必要なサービス(依存オブジェクト)を、使用する側(コンポーネントやクラス)が自ら生成するのではなく、 外部から注入するという設計手法です。たとえば、データ取得処理などのロジックを、コンポーネント内部ではなく 「WeatherService」などの外部クラスに分離し、そのクラスのインスタンスをDI経由で受け取って利用します。
サービスの定義例
たとえば、外部に以下のようなサービスクラス WeatherService があるとします:
// WeatherService.cs
public class WeatherService
{
private readonly HttpClient _http;
public WeatherService(HttpClient http)
{
_http = http;
}
public async Task<WeatherInfo[]> GetForecastAsync()
{
return await _http.GetFromJsonAsync<WeatherInfo[]>("sample-data/weather.json")
?? Array.Empty<WeatherInfo>();
}
}
サービス登録の方法
Blazor Server や Blazor WebAssembly では、以下のようにサービスを登録します:
// Program.cs
builder.Services.AddSingleton<WeatherService>();
builder.Services.AddScoped<UserState>();
builder.Services.AddTransient<ILogger, ConsoleLogger>();
ライフタイムの違いは重要です:
- Singleton: アプリケーション全体で1つのインスタンス。設定情報やキャッシュなど。
- Scoped: Blazor Serverでは「接続ごと」に1インスタンス。ユーザーごとの状態に適します。
- Transient: 利用のたびに新しいインスタンスが生成されます。ステートレスなサービス向き。
サービスの注入と利用方法
登録したサービスは、Razor コンポーネントや他のサービスから次のように注入できます。
① Razor コンポーネントでの利用(@inject ディレクティブ)
@inject WeatherService WeatherService
@code {
private WeatherInfo[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await WeatherService.GetForecastAsync();
}
}
② コンストラクタインジェクション(クラス間の依存)
サービス同士で依存する場合、コンストラクタ経由で注入します。例えば、MyComponentService が WeatherService に依存している場合:
public class MyComponentService
{
private readonly WeatherService _weatherService;
public MyComponentService(WeatherService weatherService)
{
_weatherService = weatherService;
}
public async Task<string> GetMessageAsync()
{
var data = await _weatherService.GetForecastAsync();
return $"今日は {data.First().Summary} の予報です";
}
}
このように、サービスを外部に定義し、それを必要に応じて注入することで、ロジックの再利用やテストが格段に容易になります。
補足:HttpClientの使い方(WASMの場合)
Blazor WebAssemblyでは HttpClient を使用する際に注意が必要です。以下のように、APIエンドポイントのBaseAddressを明示して登録します:
// Program.cs (Blazor WebAssembly)
builder.Services.AddScoped(sp =>
new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
このように正しくDIとライフタイムを理解して活用することで、Blazorアプリはより堅牢で柔軟な構造になります。
次のセクションでは、ScopedとSingletonの違いにより、サービスの動作がどのように変化するかを具体的に見ていきましょう。 「8.2 Scoped vs Singleton の違い」へ進みます。
下田 昌平
開発に関するインプットをアウトプットしています。検索ログ
開発・技術相談
システム開発や技術検証、要件定義の作成、アーキテクチャ設計、 テスト設計、運用設計まで、一気通貫で支援しています。 企画段階の「まず相談したい」レベルから、実装・運用まで 幅広く対応できますので、お気軽にお問い合わせください。
お問い合わせ