ASP.NET の DIコンテナ Autofac / Unity / 標準DI を業務SEが選ぶ3つの判断軸

みなさんこんにちは!ヒロポンです!

DI(依存性注入)、入れることは決めた。じゃあ次です。Autofac? Unity? それとも標準DI? どれ使うんや??ってなりますよね。

「DI入れる必要あるの?」の話は前に書いた(ASP.NETでDIって本当に必要?)ので、今回はその続き。入れると決めた人が、コンテナをどう選ぶか、つまり asp.net di コンテナ 比較 の話です。

先に結論。迷ったら、まず標準DI。規模が出てきたら Autofac。これだけ覚えて帰ってもらってもいいくらいです。

今の現場が .NET Framework 4.7.2 でも、標準DIは NuGet でちゃんと入ります。今回は学習コスト・Framework対応とCore移行・登録の書き味、この3軸で業務SE目線で選び分けていきます。

📌 動作確認メモ: この記事のコードは Docker 上の .NET で、言語仕様と登録の挙動レベルまで確認しています。IIS 上のフルアプリ統合は実機(VS)前提で読んでください。解決速度の数値は後述の通り実測です。

目次

忙しい人向けに最初にまとめ

  • 標準DI(Microsoft.Extensions.DependencyInjection) — .NET 標準・学習コスト最小・Core移行に強い。迷ったらこれ
  • Autofac — モジュール分割・アセンブリスキャンなど機能が豊富で今も活発。規模が出てきたらこれ
  • Unity — .NET Framework 時代の資産。今あるなら使えるが、新規で選ぶ理由は薄め。標準DI移行も視野に。

3つの判断軸

コンテナ選びで実際に効く軸は、この3つです。

  1. 学習コスト — チーム全員が読めるか
  2. .NET Framework 対応と Core 移行 — 今の 4.7.2 で動くか・将来 Core に移れるか
  3. 登録の書き味 — コンストラクタ注入・プロパティ注入・モジュール分割の書きやすさ

順番に見ていきます。

早見表 — 3つのコンテナを観点別に

まず全体像を1枚で。朝礼や設計レビューで「なんでこれ選んだの?」と聞かれた時の弾薬にどうぞ。

標準DI / Autofac / Unity を、学習コスト・.NET Framework対応・Core移行・モジュール分割・プロパティ注入・開発の活発さ・本命用途で比較した早見表

強い / 良い / 場合による / × 非対応 / ! 要注意。

判断軸1: 学習コスト — チーム全員が読めるか

業務系のチームでいちばん効くのが、これです。

標準DIは .NET の一部。だからドキュメントも情報も多い。AddTransient AddScoped AddSingleton の3つを覚えれば8割書けます。新人に引き継いでも、検索すればいい感じに答えが出てくる。

Autofac は機能が豊富なぶん、覚えることが多いです。Module でまとめたり、RegisterAssemblyTypes で一括登録したり。便利なんだけど、「これ何やってるの?」が増える。チーム全員が読めるかは要注意です。

Unity はシンプル寄りで学習コストは低め。ただ情報が古いものが多くて、新しい例が見つけにくいんですよね。

一行教訓: チームの平均値で選ぶ。自分が書けても、引き継ぐ人が読めなきゃ意味がない。

判断軸2: .NET Framework 対応と Core 移行 — 4.7.2 の現場から見る

.NET Framework 4.7.2 の現場だと、ここが地味に効きます。

Autofac と Unity は、もともと .NET Framework 時代から使われてきたツール。だからネイティブに動く。何も考えず入ります。

標準DIも、実は NuGet で Microsoft.Extensions.DependencyInjection を入れれば 4.7.2 で動きます。ん?Core 専用ちゃうの?と思われがちだけど、違うんですよね。

で、ここがポイント。将来 .NET Core / .NET 8+ に移行する予定があるなら、標準DIで書いておくと移行がほぼゼロコスト。ASP.NET Core は標準DIが組み込みなので、登録コードがそのままいい感じに動く。Autofac/Unity だと、移行のタイミングで書き換えが要ることがあります。

今の現場が「4.7.2 のまま当分動かない」なら Autofac でもいい。でも「いつか Core に行くかも」が頭の片隅にあるなら、標準DIに寄せておくのが効きます。

一行教訓: 標準DIは「Core移行の保険」。今動くだけでなく、3年後の自分を楽にする。

判断軸3: 登録の書き味 — 同じことを3つで書き比べる

最後は実際のコード。同じ「IOrderService を解決する」を、3つで書き比べてみます。

まず標準DI。

// 標準DI (Microsoft.Extensions.DependencyInjection)
var services = new ServiceCollection();
services.AddTransient<IRepository, SqlRepository>();
services.AddScoped<IOrderService, OrderService>();

var provider = services.BuildServiceProvider();
var svc = provider.GetRequiredService<IOrderService>();

Add{ライフタイム}<インターフェース, 実装> の形。素直で、読めば分かる。

次に Autofac。

// Autofac
var builder = new ContainerBuilder();
builder.RegisterType<SqlRepository>().As<IRepository>();
builder.RegisterType<OrderService>().As<IOrderService>();

var container = builder.Build();
var svc = container.Resolve<IOrderService>();

RegisterType<実装>().As<インターフェース>() の流れ。慣れると読みやすいし、ここに .SingleInstance().PropertiesAutowired() を生やせる拡張性があります。

最後に Unity。

// Unity
var container = new UnityContainer();
container.RegisterType<IRepository, SqlRepository>();
container.RegisterType<IOrderService, OrderService>();

var svc = container.Resolve<IOrderService>();

RegisterType<インターフェース, 実装> で、標準DIと Autofac の中間くらいの書き味。なお NuGet のパッケージ名は Unity.Container(あわせて Unity.Abstractions)、名前空間は using Unity; です。ゲームエンジンの Unity と紛らわしいので、ここだけ注意。

書き味だけ見ると、3つともこんな感じで大きくは変わりません。差が出るのは、アセンブリ一括登録やモジュール分割みたいな「規模が出てきた時の機能」。そこが要るかどうかが分かれ目です。

解決速度はどうか — 10万回 Resolve して実測

「で、結局どれが速いん??」も気になりますよね。実際に測りました。同じ依存グラフ(IOrderServiceIRepository)を、各コンテナで10万回 Resolve した合計時間です。

標準DI・Unity・Autofac で同じ依存グラフを10万回 Resolve した合計時間の棒グラフ。標準DIが最速、Autofacが最も重く、Unityはその中間

標準DIが圧倒的に速くて、Autofac がいちばん重い。Unity はその中間。順番はこれで安定してました。

ただ、これは10万回まわした合計の話です。1回あたりに直すと、いちばん重い Autofac でも約0.002ミリ秒。実アプリで1リクエストに数個 Resolve するくらいなら、体感はゼロです。

だから、速度でコンテナを選ぶ必要は、ほぼない

(Stopwatch ベースの計測なので、BenchmarkDotNet みたいな精密さはありません。数値そのものはマシンや負荷で前後するので、相対の傾向だけ参考にしてください。)

選ぶべきは、速度より学習コストと移行性。そこで決めるのが、業務系では現実的な得につながります。

結論: 迷ったらまず標準DI、規模が出てきたら Autofac

3軸を通すと、答えはシンプルになります。

  • 新規で、標準的な構成で、Core移行も視野にある標準DI。学習コストも移行コストも最小。
  • 大規模で、モジュール分割やアセンブリスキャンが要るAutofac。機能の豊富さが効いてくる。
  • 既に Unity で動いてる資産がある → 無理に変えず保守。新規で Unity を選ぶ理由は薄い。

業務系の現場の8割は、標準DIで足ります。足りなくなってから Autofac に乗り換えても遅くない。最初から多機能なものを入れて、チームが読めなくなるほうがよっぽど事故ります。シンプルさは正義です!!

ハマりポイント

俺自身も最初ハマったやつ含めて、DIコンテナで詰まるパターンを3つ。

  • ライフタイムの取り違え: SingletonScoped を注入して状態が混ざる。標準DIは検証で気づけるけど、設計時に「これはリクエスト単位?アプリ単位?」を決めておくのが先。
  • 標準DIをCore専用だと思い込む: 4.7.2 でも NuGet で入るのに、「Frameworkだから Autofac しかない」と決めつけて選択肢を狭めてた現場、けっこう見ます。
  • 多機能コンテナの入れすぎ: 小規模なのに Autofac のフル機能を使って、引き継ぎで詰まる。機能は要るぶんだけ。

よくある質問

Q1. 結局どれを選べばいいですか?

迷ったら標準DI(Microsoft.Extensions.DependencyInjection)です。.NET標準で学習コストが低く、Core移行とも相性が良い。アセンブリ一括登録やプロパティ注入など、標準DIで手薄な機能が必要になったら Autofac を検討する。この順番で十分です。

Q2. .NET Framework 4.7.2 でも標準DIは使えますか?

使えます。NuGet で Microsoft.Extensions.DependencyInjection を入れれば動きます。Core専用ではありません。将来 .NET 8+ へ移行する可能性があるなら、標準DIで書いておくと移行コストがほぼゼロになります。

Q3. 今 Unity を使っています。乗り換えるべきですか?

動いているなら、急いで乗り換える必要はありません。ただ、新規の登録部分から少しずつ標準DIに寄せておくと、将来の選択肢が広がります。一気に全部やると事故るので、新しく書く所からが安全です。

Q4. 解決速度の差は気にすべきですか?

ほとんどの業務アプリでは気にしなくて大丈夫です。後述の実測でも、コンテナ間の差は実アプリの処理時間に対して誤差レベル。速度より、学習コストと移行性で選ぶほうが現実的な得につながります。

次に読むべき記事

DIコンテナ選びで迷ってる同業がいたら、この記事ぶん投げてやってください。どんどんシェア待ってるぜ!!

以上!

執筆者

バイブス父さん — 業務 SE 7 年 (SIer 正社員 2 / フリーランス 5)。現職は SEO 直轄部の AI アドバイザー兼 PL、副業で中小 SIer の CTO。SIer の正社員からフリーランスに転じ、複数のエージェント経由で案件を回してきた経験ベースで「業務 SE 視点」の技術 + キャリア記事を書いています。

🐦 X: @hiro_progra0524 (日々の現場メモ更新中)
📝 About Me で経歴詳細を見る


この記事が気に入ったら
いいねしてね!

どんどんシェア待ってるぜ!!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次