カテゴリ: C# 更新日: 2026/06/06

ASP.NET Coreで学ぶC#の依存性注入(DI)入門!初心者向け完全ガイド

C#のASP.NETで依存性注入(DI)を活用する方法
C#のASP.NETで依存性注入(DI)を活用する方法

先生と生徒の会話形式で理解しよう

生徒

「C#を使ってWebアプリの開発に挑戦しているのですが、依存性注入とかDIという言葉がよく出てきて意味が分かりません。これは何ですか?」

先生

「それはWebアプリ開発でとても大切な仕組みですね。依存性注入とは、プログラムの部品を外から組み立てて、変更やテストを簡単にするための設計図のようなものです。」

生徒

「パソコンも触ったばかりの私には、少し難しそうです。具体的にどのような仕組みで、どのようにプログラムを書けば良いのでしょうか?」

先生

「安心してください。今回は初心者の方でも絶対に理解できるように、日常生活の簡単な例えを使いながら、実際のプログラムの書き方まで順番に解説していきますね!」

1. 依存性注入(DI)とは?

1. 依存性注入(DI)とは?
1. 依存性注入(DI)とは?

C#のWebアプリ開発、特にASP.NET Core(エーエスピーネットコア)という枠組みを勉強していると、必ず出会うのが依存性注入(いぞんせいちゅうにゅう)です。英語ではDependency Injection(デペンデンシー・インジェクション)と呼び、頭文字を取ってDI(ディーアイ)と略されます。

文字だけを見ると非常に難しそうですが、仕組みはシンプルです。プログラムにおける「依存」とは、「ある部品が動くために、別の部品を必要としている状態」を指します。そして「注入」とは、「必要な部品を外から差し込むこと」を意味します。

プログラミング未経験の方に向けて、身近な例えで説明しましょう。例えば、あなたが「ゲーム機」だとします。ゲーム機は「カセット」がないと遊べません。このとき、ゲーム機はカセットに依存していると言えます。もしゲーム機の中に最初から特定のゲームが埋め込まれていて、外から交換できないとしたら不便ですよね。他のゲームで遊びたくなったら、ゲーム機ごと買い替えなければなりません。

そこで、ゲーム機本体にはカセットを差し込む「穴(インターフェース)」だけを用意しておき、中身のカセットは外から自由に差し替えられるようにします。この「外からカセットを差し込む仕組み」こそが、プログラミングの世界における依存性注入(DI)なのです。この仕組みを使うことで、プログラムの一部を書き換えたいときに、他の場所を汚さずに特定の部品だけを簡単に交換できるようになります。

2. なぜWebアプリ開発でDIが必要なのか

2. なぜWebアプリ開発でDIが必要なのか
2. なぜWebアプリ開発でDIが必要なのか

C#で本格的なWebアプリを作るとき、なぜこのDIという考え方が重要になるのでしょうか。その理由は、アプリの規模が大きくなったときに、修正や管理が圧倒的に楽になるからです。

例えば、インターネットでお買い物ができるショッピングサイトを想像してください。このアプリには、注文を受け付けたあとに「お買い物ありがとうございます」というメールを自動で送信する機能があるとします。最初は普通のメールを送信する部品を使っていましたが、後から「LINEで通知を送るように変更したい」とか、「スマートフォンにプッシュ通知を送りたい」と要望が変わることがよくあります。

もしDIを使っていない場合、注文処理のプログラムそのものを書き換える必要が出てきます。注文処理のプログラムは、お金の計算など大切な処理がたくさん書かれている場所です。そこを何度も書き換えていると、間違えて別の場所を壊してしまう危険があります。パソコンの操作に慣れていない時期に、複雑なコードを何度も触るのは怖いですよね。

しかし、DIを活用しておけば、注文処理のプログラムは一切触る必要がありません。外から差し込む部品を「メール送信部品」から「LINE送信部品」に切り替えるだけで、安全に新しい機能へと変更できます。このように、プログラムの安全性を保ちながら、時代の変化に合わせてアプリを成長させるために、DIは必須の技術となっています。

3. 依存性注入の基本となるインターフェースの役割

3. 依存性注入の基本となるインターフェースの役割
3. 依存性注入の基本となるインターフェースの役割

DIを正しく使うためには、インターフェース(Interface)というC#の機能を知る必要があります。プログラミングにおいて、インターフェースとは「部品の取扱説明書」「共通の規格」のようなものです。

先ほどのゲーム機の例えを思い出してください。任天堂のゲーム機に、他社の全く異なる形のカセットを差し込もうとしても、形が合わなくて差し込めませんよね。これはカセットの「規格(形やサイズ)」が違っているからです。プログラムでも同じで、外から部品を差し込むためには、差し込まれる側と差し込む側の「接続口の形」を一致させる必要があります。

C#のインターフェースは、その接続口の形を定義する役割を持っています。例えば、「この部品は必ず『送信する』というボタンを持っていなければならない」というルールをインターフェースで決めておきます。実際の部品を作る人は、そのルールに従って中身を作ります。これにより、どんな部品であっても接続口の形が同じになるため、Webアプリの中で自由に入れ替えることができるようになるのです。

4. 最もシンプルなDIのプログラムを書いてみよう

4. 最もシンプルなDIのプログラムを書いてみよう
4. 最もシンプルなDIのプログラムを書いてみよう

それでは、実際にC#のコードを見ていきましょう。まずは、挨拶を表示するだけの非常にシンプルなプログラムを使って、DIの構造を学びます。ここでは、メッセージを準備する部品を、表示する画面に外から注入する流れを作ります。

まずは、共通の規格となるインターフェースと、その中身となる実際の部品を作ります。最初の部品は、日本語で挨拶を返す部品にしましょう。


// 共通の規格(インターフェース)を定義します
public interface IGreetService
{
    string GetMessage();
}

// 規格に従って、日本語の挨拶を返す部品を作ります
public class JapaneseGreetService : IGreetService
{
    public string GetMessage()
    {
        return "こんにちは!お元気ですか?";
    }
}

次に、この部品を利用する側のプログラムを書きます。ポイントは、利用する側は「日本語の挨拶部品」を直接指定するのではなく、共通の規格である「IGreetService」だけを指定して待っている点です。このように、部品を受け取るための窓口(構造)をコンストラクタと呼びます。コンストラクタは、そのクラスが作られるときに最初に動く特殊な命令です。


// 挨拶を表示するコントローラー(Webアプリの画面制御を行う場所)
public class HomeController
{
    // 共通規格の窓口を用意します
    private readonly IGreetService _greetService;

    // コンストラクタを使って、外から部品を注入(受取)します
    public HomeController(IGreetService greetService)
    {
        _greetService = greetService;
    }

    // 画面にメッセージを表示する命令です
    public string Show()
    {
        return _greetService.GetMessage();
    }
}

このプログラムを実行すると、外から渡された部品に応じてメッセージが変わります。もし日本語の部品が渡されていれば、画面には以下のように出力されます。


こんにちは!お元気ですか?

5. 部品を切り替える別パターンのプログラム

5. 部品を切り替える別パターンのプログラム
5. 部品を切り替える別パターンのプログラム

DIの凄さを実感するために、別のパターンのプログラムを用意しました。今度は、英語で挨拶を返す部品を新しく作ってみましょう。先ほど作った共通の規格(IGreetService)はそのまま使い、中身だけを英語用に変更します。


// 同じ規格に従って、英語の挨拶を返す新しい部品を作ります
public class EnglishGreetService : IGreetService
{
    public string GetMessage()
    {
        return "Hello! How are you?";
    }
}

新しい部品が完成しました。ここで注目してほしいのは、先ほど作った「HomeController」という利用側のプログラムは、1文字も書き換える必要がないということです。HomeControllerは、ただ規格に合う部品が届くのを待っているだけなので、届いたものが日本語だろうと英語だろうと、そのまま動かすことができます。

もし、この英語の部品を外から注入して実行した場合、出力結果は自動的に以下のように切り替わります。


Hello! How are you?

このように、利用する側のプログラムを汚さずに、部品の設定を変更するだけでアプリの挙動をガラリと変えられるのが、DIの最大のメリットです。これにより、開発者は新しい機能を安全に追加していくことができます。

6. ASP.NET CoreでDIを登録・設定する方法

6. ASP.NET CoreでDIを登録・設定する方法
6. ASP.NET CoreでDIを登録・設定する方法

ここまでの説明で、部品の作り方と受け取り方は分かりました。では、実際に「どの規格に、どの部品を組み合わせるか」という決定は、どこで行うのでしょうか。ASP.NET Coreでは、アプリが起動するときに一括してその設定を行う特別な場所が用意されています。

C#のWebアプリプロジェクトの中には、「Program.cs(プログラムシーエス)」という名前のファイルが存在します。これが、アプリ全体の初期設定を書くためのメインのファイルです。このファイルの中に、「このインターフェースが呼ばれたら、このクラスを注入してください」という登録のコードを記述します。

具体的な登録の書き方は、以下のようになります。builder.Servicesの後に続く命令を使って登録を行います。


var builder = WebApplication.CreateBuilder(args);

// ここでDIの登録を行います!
// 「IGreetService」が必要と言われたら「JapaneseGreetService」を渡すという意味です
builder.Services.AddTransient<IGreetService, JapaneseGreetService>();

var app = builder.Build();

もし英語の挨拶に変えたくなったら、このProgram.csの1行を以下のように書き換えるだけで、アプリ全体の機能が英語に切り替わります。他のファイルを一切探す必要はなく、この設定ファイルだけを見れば、どの部品がどこに使われているかが一目で分かるようになります。


// 英語の部品に切り替える場合は、ここを書き換えるだけです
builder.Services.AddTransient<IGreetService, EnglishGreetService>();

7. DIの寿命(ライフサイクル)を理解しよう

7. DIの寿命(ライフサイクル)を理解しよう
7. DIの寿命(ライフサイクル)を理解しよう

ASP.NET CoreでDIを使うとき、知っておかなければならない重要な基本知識として、部品の寿命(ライフサイクル)があります。Webアプリは、世界中のたくさんの人が同時にアクセスしてくる場所です。そのため、部品を「いつ作って、いつ破棄するか」を適切に管理しないと、パソコンのメモリを無駄遣いしてしまい、アプリが重くなる原因になります。

ASP.NET CoreのDIには、主に3つの寿命の指定方法が用意されています。用途に合わせて使い分けることで、効率的なWebアプリが作れます。登録するときに使う命令の名前がそれぞれ異なります。

寿命の名前 C#での登録命令 仕組みと特徴
トランジエント AddTransient 部品が必要とされるたびに、毎回新しく作り直します。状態を持たないシンプルな処理に最適です。
スコープド AddScoped Webブラウザからの1回のアクセス(リクエスト)の間だけ同じ部品を使い回します。画面を表示する一連の処理で同じデータを使いたいときに便利です。
シングルトン AddSingleton アプリが起動してから終了するまで、たった1つの部品をずっと全員で使い回します。システム共通の設定情報などに使います。

プログラミング未経験の方は、まずは一番安全でトラブルが起きにくい「Transient(トランジエント)」を基本として覚えておくと良いでしょう。毎回新しく部品を作ってくれるため、古いデータが残ってバグになる心配がありません。アプリの仕組みに慣れてきたら、データの保存管理などのために他の寿命も試してみてください。

8. Webアプリの画面へデータを渡す実践コード

8. Webアプリの画面へデータを渡す実践コード
8. Webアプリの画面へデータを渡す実践コード

最後に、実際のWebアプリ開発でよく使われる、HTMLの画面にDIで取得したデータを表示させる具体的な流れを確認しましょう。これまでの知識をすべて組み合わせた実践的な内容です。

まずは、画面を制御するコントローラーのコードです。DIを使って挨拶のメッセージを取得し、それをWebアプリの画面(ビュー)に引き渡す処理を書きます。


using Microsoft.AspNetCore.Mvc;

public class WelcomeController : Controller
{
    private readonly IGreetService _greetService;

    // DIによって必要な部品が自動的に注入されます
    public WelcomeController(IGreetService greetService)
    {
        _greetService = greetService;
    }

    public IActionResult Index()
    {
        // 部品からメッセージを取得して、画面に渡す箱(ViewData)に入れます
        ViewData["Message"] = _greetService.GetMessage();
        return View();
    }
}

次に、このメッセージを表示するためのHTML側のファイル(Index.cshtml)の書き方です。C#のWebアプリでは、HTMLの中に「@」を付けることで、プログラムの変数を埋め込んで表示することができます。これをRazor(レイザー)構文と呼びます。


<div class="container mt-5">
    <div class="alert alert-success" role="alert">
        <h4 class="alert-heading">システムからの通知</h4>
        <p>@ViewData["Message"]</p>
    </div>
</div>

このプログラムを動かすと、HTMLの「@ViewData["Message"]」の部分が、DIによって注入された部品のメッセージに自動的に置き換わります。Program.csでの登録内容を変えるだけで、HTMLファイルを直接書き換えることなく、画面に表示される文言を日本語や英語に自由に変更できるようになります。これが、C#とASP.NET Coreにおける、DIを活用したWebアプリ開発の強力な第一歩です。

カテゴリの一覧へ
新着記事
New1
COBOL
COBOLのデバッグ方法を徹底解説!初心者向けDISPLAY活用ガイド
New2
C#
C#のLINQでグループ化と集計!GroupByとCountを初心者向けに解説
New3
C#
C#のシングルトンパターン実装方法と注意点を徹底解説!初心者向け完全ガイド
New4
Azure
Azure WAFの誤検知を解消!除外リスト設定とチューニング方法を初心者向けに徹底解説
人気記事
No.1
Java&Spring記事人気No1
C#
C#の文字列を数値に変換する方法(int.Parse・TryParse)をわかりやすく解説!
No.2
Java&Spring記事人気No2
COBOL
COBOLの数値データ型「PIC 9」の使い方と注意点をやさしく解説!
No.3
Java&Spring記事人気No3
C#
C#のbool型を完全解説!初心者でもわかるtrueとfalseの基本と使い方
No.4
Java&Spring記事人気No4
C#
C#のトランザクション処理を完全ガイド!初心者でもわかるCommit・Rollbackの使い方
No.5
Java&Spring記事人気No5
C#
C#のラムダ式の書き方と構文を初心者向けに完全解説
No.6
Java&Spring記事人気No6
C#
C#のLINQでOrderByを使った並び替えを完全ガイド!初心者でもわかるソート方法
No.7
Java&Spring記事人気No7
Azure
Azureストレージの冗長性比較!LRS/GRS/ZRSの選び方とコストの最適解を完全解説
No.8
Java&Spring記事人気No8
COBOL
COBOLのコンパイラと開発環境を徹底解説!初心者にもわかりやすい入門ガイド