C# Academy · レッスン

DIコンテナーの基礎

制御の反転、サービスの登録、.NET DIコンテナーによる依存関係の解決方法を理解します。

レッスン 1/413 ステップ

「DIコンテナーの基礎」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

依存性の注入とは

Dependency Injection (DI) は、クラスが依存関係を自ら作成するのではなく、外部のソースから受け取るデザインパターンです。

クラス内にvar repo = new UserRepository();と記述する代わりに、クラスは必要なものを宣言し、DI コンテナーがそれを提供します。

制御の反転

DI は制御の反転 (Inversion of Control、IoC)原則を具体的に実装したものです。依存関係を作成する制御が、依存するクラスから外部のコンテナーへと反転します。

これにより、クラスのテストや置き換えが容易になります。

.NET DI コンテナーの設定

.NET アプリでは、DI コンテナーをProgram.cs内のIServiceCollectionを使って構成します。サービスを登録すると、実行時に解決されます。

var builder = WebApplication.CreateBuilder(args);

// Register services
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddScoped<UserService>();

var app = builder.Build();
app.Run();

インターフェイスと実装の定義

DIは、インターフェイスを前提にプログラミングすると最も効果を発揮します。サービス契約用のインターフェイスと、それを実装する具象クラスを定義します。

public interface IUserRepository
{
    User? GetById(int id);
}

public class UserRepository : IUserRepository
{
    public User? GetById(int id)
    {
        // fetch from database
        return new User { Id = id, Name = "Alice" };
    }
}

コンストラクターによるサービスの解決

コンテナーは、登録済みサービスをコンストラクターに自動的に注入します。クラスは必要なインターフェイスを宣言するだけでよく、newキーワードは必要ありません。

public class UserService
{
    private readonly IUserRepository _repo;

    public UserService(IUserRepository repo)
    {
        _repo = repo;
    }

    public User? FindUser(int id) => _repo.GetById(id);
}

複数のサービスの登録

必要な数だけサービスを登録できます。一般的な拡張メソッドにはAddTransient、AddScoped、AddSingletonがあり、それぞれ異なるライフタイムを定義します。

builder.Services.AddSingleton<IConfig, AppConfig>();
builder.Services.AddScoped<IUserRepository, UserRepository>();
builder.Services.AddTransient<IEmailService, SmtpEmailService>();
builder.Services.AddScoped<UserService>();

IServiceProviderの直接使用

まれに、命令的にサービスを解決する必要があります。IServiceProviderを使用するとGetRequiredService<T>()を呼び出してサービスを解決できますが、ほとんどの場面ではコンストラクターインジェクションを優先してください。

// Anti-pattern (service locator) — use sparingly
public class ManualResolver
{
    private readonly IServiceProvider _sp;

    public ManualResolver(IServiceProvider sp) => _sp = sp;

    public void DoWork()
    {
        var svc = _sp.GetRequiredService<UserService>();
        svc.FindUser(1);
    }
}

オープンジェネリックの登録

.NET DIはオープンジェネリックの登録をサポートしています。IRepository<>を一度登録すると、任意のエンティティ型に対してRepository<T>に解決できます。

builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

// Resolves as:
// IRepository<User> -> Repository<User>
// IRepository<Order> -> Repository<Order>

起動時の検証

ValidateOnStart()またはValidateScopes = trueを使用すると、コンテナーは、Singleton内にScopedサービスを保持するような登録ミスを、実行時ではなくアプリケーションの起動時に検出できます。

builder.Services.AddScoped<IMyService, MyService>();

// Detect scope violations at startup
builder.Host.UseDefaultServiceProvider(options =>
{
    options.ValidateScopes = true;
    options.ValidateOnBuild = true;
});

サービスのデコレーション

元のクラスを変更せずに、デコレーターでサービスをラップできます。まず内部のサービスを登録し、その後にそれをラップするデコレーターを登録します。

builder.Services.AddScoped<IUserRepository, UserRepository>();

// Decorator pattern
builder.Services.Decorate<IUserRepository, CachedUserRepository>();
// Requires Scrutor NuGet package

実践例: DIを使用したMinimal API

Minimal APIでは、サービスがルートハンドラーのパラメーターに直接注入されます。コンテナーがサービスを自動的に解決します。

app.MapGet("/users/{id}", (int id, UserService svc) =>
{
    var user = svc.FindUser(id);
    return user is null ? Results.NotFound() : Results.Ok(user);
});

クイックチェック

ほとんどのクラスで依存関係を取得する際に、どの方法を優先すべきですか。

まとめ: DIコンテナーの基礎

重要なポイント:

  • DIでは依存関係の生成を逆転させます。クラス自身ではなく、コンテナーがオブジェクトを構築します
  • AddTransient / AddScoped / AddSingletonでサービスを登録します
  • コンストラクターインジェクションが標準的かつ推奨される方法です
  • オープンジェネリック、デコレーター、ValidateOnBuildは強力な高度機能です
無料で開始

AI チューターと学ぶ C# — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
93
レッスン
346

よくある質問

「DIコンテナーの基礎」レッスンは無料ですか?

はい。「DIコンテナーの基礎」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「DIコンテナーの基礎」で何を学びますか?

制御の反転、サービスの登録、.NET DIコンテナーによる依存関係の解決方法を理解します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「DIコンテナーの基礎」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. DIコンテナーの基礎
  2. サービスのライフタイム:Transient、Scoped、Singleton
  3. コンストラクターインジェクションとインターフェース
  4. FactoryとOptionsパターン
← C# Academyに戻る