Skip to content

MS_ASPNETCoreDI

nishi_74322014 edited this page Aug 21, 2026 · 1 revision

ASP.NET Core における DI

概要

参考

詳細

構成

参考

※ 詳しくはコチラを参照。

対象

  • ConfigureServices メソッドでの登録メソッドによりライフサイクルが変わってくる。

    • AddSingleton : アプリケーションにて共有のシングルトンインスタンスを作成する。
    • AddScoped : Web リクエストごとに新しいインスタンスを作成する。
    • AddTransient : Dependency が要求されるごとに新しいインスタンスを作成する。
  • Configure メソッドには、ConfigureServices メソッドで登録したサービスが、
    IApplicationBuilder や引数を経由で渡されるので、これを使用して構成する。

移行メモ(誤記): 原文の「AddSigleton」は
AddSingleton の誤記と判断し修正した。

補足(Startup.cs は無くなった/最新化): 本節が前提とする
**Startup クラス(ConfigureServices / Configure)**は、
.NET 6 の最小ホスティング モデルにより、既定では生成されなくなった

〜.NET 5 .NET 6 以降
構成の場所 Startup.cs の 2 メソッド Program.cs の 1 ファイル
サービス登録 ConfigureServices(IServiceCollection) builder.Services.Add~
パイプライン Configure(IApplicationBuilder, ...) app.Use~
// .NET 6 以降(Program.cs のみ)
var builder = WebApplication.CreateBuilder(args);

// ← 旧 ConfigureServices に相当
builder.Services.AddControllersWithViews();
builder.Services.AddScoped<IOrderRepository, SqlOrderRepository>();

var app = builder.Build();

// ← 旧 Configure に相当
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();

app.Run();

Startup を使い続けることも可能
builder.Services に手で渡す形にすれば動く)だが、
新規テンプレートは生成しない。
移行の詳細は ASP.NET Coreへの移行 を参照。

ライフタイムの意味は変わっていないので、
本節の 3 つの説明は現在もそのまま有効である
(選択の指針と事故例は DI の「コンテナー」節を参照)。

Controller

補足(使い分け): 2 つの注入方法は、使う頻度で選ぶ

方法 書き方 適する場面
Constructor public HomeController(IFoo foo) 多くのアクションで使う
Action([FromServices] Index([FromServices] IFoo foo) 1 つのアクションでしか使わない(重いサービス等)
public sealed class OrderController(IOrderService svc) : Controller
{
    // 全アクションで使うものは constructor
    public IActionResult Index() => View(svc.List());

    // ここでしか使わない重いものは Action 注入
    public IActionResult Report([FromServices] IReportGenerator gen)
        => File(gen.Build(), "application/pdf");
}

.NET 7 以降では [FromServices] の省略が可能になった
(登録済みの型なら、属性なしでも DI から解決される)。
ただし明示した方が読み手に意図が伝わるため、
属性を付ける運用でも問題ない。

なお、Minimal API でも同じ仕組みが働く。

app.MapGet("/orders", (IOrderService svc) => svc.List());

View

  • View インジェクション

    • @inject [サービスの型] [変数名]
    • Model プロパティ風(@model ViewModel のクラス型)

に書く。

補足(使いどころは限定する): @inject は便利だが、
ビューにロジックを持ち込む入口にもなる。

@inject IStringLocalizer<HomeController> L
@inject IOptions<SiteOptions> Options

<h1>@L["Welcome"]</h1>
<p>@Options.Value.SiteName</p>

適切な用途:

  • ローカライズIStringLocalizerIViewLocalizer
  • 設定値の参照IOptions<T>
  • 表示専用のヘルパーIHtmlLocalizer 等)

避けるべき用途:

  • リポジトリや DbContext を注入してビューから DB を引く
    (N+1 クエリ、例外処理の欠落、テスト不能)

表示に必要なデータは、コントローラーで揃えて ViewModel に載せるのが原則。
@inject は「ビュー自身の関心事」に限って使う。

コンテナを変更する。

ASP.NET Core では、

  • 既定では、Microsoft.Extensions.DependencyInjection を使用する。
  • ConfigureServices メソッドが、IServiceProvider を返すようにシグネチャを変更する方法で、
    Autofac (Autofac.Extensions.DependencyInjection) など、
    別のコンテナに切替可能らしい。

補足(現在の差し替え方/最新化): 原文が述べる
ConfigureServicesIServiceProvider を返す」方式は
ASP.NET Core 2.x 時代のもので、
.NET Core 3.0 以降は非対応になった
(スコープ検証が働かない等の問題があったため)。

現在は UseServiceProviderFactory を使う。

var builder = WebApplication.CreateBuilder(args);

// 標準の登録はそのまま書ける
builder.Services.AddControllers();

// コンテナーを Autofac に差し替える
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(cb =>
{
    cb.RegisterModule<MyModule>();          // Autofac 固有の登録
    cb.RegisterType<Foo>().As<IFoo>().PropertiesAutowired();
});

要点: IServiceCollection への登録は標準の作法のままでよく、
固有機能が必要な部分だけを ConfigureContainer に書く
このため、まず標準で始めて、後から差し替えるという順序が取れる。

差し替える動機(標準に無い機能)は
.NET Core における DI の表を参照。
なお .NET 8 のキー付きサービスにより、
「名前で使い分けたい」という代表的な動機は標準で満たせるようになった。

参考

Microsoft Learn

Qiita

時が癒す

ASP.NET Core MVC のDIコンテナを利用する

Autofac


Tags: 移行, プログラミング, .NET開発, .NET Core, ASP.NET, ASP.NET MVC

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally