技術共有

C# IOC コンテナー、依存関係の注入と制御の反転

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

制御の反転 (IoC)

意味 : 制御の反転は、従来のプログラミングにおける制御の流れを逆転させる設計原則です。従来のプログラミング モデルでは、コンポーネント間の依存関係はコンポーネント自体によって内部的に作成および維持されます。制御モードの反転では、この依存関係は外部コンテナー (Spring フレームワーク、.NET の Microsoft.Extensions.DependencyInjection など) によって管理されます。コンポーネントは独自の依存関係を担当しなくなり、すべての依存関係を注入します。必要な依存関係を介して。

本旨: オブジェクトの作成とオブジェクト間の依存関係の管理を、オブジェクト自体から外部コンテナに移します。

アドバンテージ

  • カップリングを減らす: コンポーネント間の依存関係がハードコーディングされなくなったため、コンポーネントの実装をより簡単に置き換えることができ、システムの柔軟性と保守性が向上します。
  • モジュール性の向上: 個々のコンポーネントは、特定の実装に依存せず、抽象インターフェイスまたは抽象クラスに依存するため、独立して開発およびテストできます。
  • テストが簡単: コンポーネント間の依存関係は外部化されるため、モック オブジェクトまたはテスト スタブを使用して単体テストの依存関係をシミュレートする方が簡単です。

依存性注入 (DI)

意味 : 依存性の注入は、制御の反転を実現するための具体的な方法です。これには、クラス自体に依存関係 (サービスまたはオブジェクト) を作成させるのではなく、依存関係 (サービスまたはオブジェクト) をクラスに渡すことが含まれます。

実現方法

  • コンストラクターインジェクション : 依存関係は、クラスのコンストラクターを通じて提供されます。これは、C# で最も一般的で推奨される DI の形式です。
  • プロパティ注入 : クラスのパブリック プロパティを通じて依存関係を割り当てます。このアプローチは柔軟性を提供しますが、内部状態が公開され、カプセル化が減少する可能性があります。
  • メソッドインジェクション : メソッドのパラメーターを通じて依存関係を渡します。特定のメソッドで必要な依存関係のみを注入するのに適しています。

IOCコンテナ

意味 :IOC コンテナは、オブジェクトのライフサイクルと依存関係を管理するためのフレームワークです。構成 (XML ファイル、注釈、コード構成など) に基づいてオブジェクトを自動的に作成し、これらのオブジェクトに依存関係を注入します。

効果

  • オブジェクトの作成: 設定に基づいてオブジェクト インスタンスを自動的に作成します。
  • 依存性注入: 依存関係をオブジェクトに注入して、制御の反転を実現します。
  • ライフサイクル管理: リソースの作成、破壊、リサイクルなど、オブジェクトのライフサイクルを管理します。

IOC コンテナを使用して依存関係を管理する

C# では、Microsoft.Extensions.DependencyInjection (.NET Core 以降のバージョンの組み込み DI コンテナー)、Autofac など、さまざまな IOC コンテナーを使用して依存関係を管理できます。以下では、Microsoft.Extensions.DependencyInjection を例として、IOC コンテナーを使用して C# プロジェクトの依存関係を管理する方法を紹介します。

ステップ 1: サービスに登録する

サービスは通常、.NET アプリケーションで使用されます。Program.csまたはStartup.cs(ASP.NET Core プロジェクトの場合) で使用されますIServiceCollection登録するインターフェース。

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IMyService, MyService>(); // 将MyService注册为单例服务
    // 其他服务注册
}
  • 1
  • 2
  • 3
  • 4
  • 5
ステップ 2: 依存関係を挿入する

コンストラクターを通じてコン​​トローラー、サービス、またはその他のクラスに依存関係を注入します。

public class MyController : Controller
{
    private readonly IMyService _myService;

    public MyController(IMyService myService)
    {
        _myService = myService;
    }

    // ... 控制器的其他代码
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上の例では、MyControllerクラスはコンストラクターを通じて注入されますIMyServiceインターフェースの実装 (すなわち、MyService親切)。このようにすると、MyControllerIOC コンテナは作成されると自動的にIMyService実装はコンストラクターに注入されます。

予防
  • インターフェースベースの抽象化を使用する: 柔軟性とテスト容易性を高めるために、依存型にはインターフェイスまたは抽象クラスを優先します。
  • シングルトンの過度の使用を避ける: シングルトン サービスは、状態に関連した問題を避けるために注意して使用する必要があります。
  • オブジェクトのライフサイクルを監視する: リソースの使用状況を効果的に管理するために、依存関係 (シングルトン、スコープ、一時) のライフ サイクルを理解します。