トレーニング
モジュール
ASP.NET Core で依存関係の挿入を使用してサービスを構成する - Training
ASP.NET Core アプリの依存関係の挿入を理解して実装します。 ASP.NET Core の組み込みのサービス コンテナーを使用して依存関係を管理します。 サービスをサービス コンテナーに登録します。
このブラウザーはサポートされなくなりました。
Microsoft Edge にアップグレードすると、最新の機能、セキュリティ更新プログラム、およびテクニカル サポートを利用できます。
ASP.NET Core では、ビューへの依存関係の挿入をサポートしています。 この機能は、ビュー要素を作成するためだけに必要なローカライズやデータなど、ビュー固有のサービスに役立ちます。 ビューに表示されるデータのほとんどは、コントローラーから渡されます。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
appsettings.json
や appsettings.Development.json
などの設定ファイルの値は、ビューに挿入できます。 appsettings.Development.json
の を考えてみましょう:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"MyRoot": {
"MyParent": {
"MyChildName": "Joe"
}
}
}
次のマークアップは、Razor Pages ビューに構成値を表示します:
@page
@model PrivacyModel
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
@{
ViewData["Title"] = "Privacy RP";
}
<h1>@ViewData["Title"]</h1>
<p>PR Privacy</p>
<h2>
MyRoot:MyParent:MyChildName: @Configuration["MyRoot:MyParent:MyChildName"]
</h2>
次のマークアップは、MVC ビューに構成値を表示します:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
@{
ViewData["Title"] = "Privacy MVC";
}
<h1>@ViewData["Title"]</h1>
<p>MVC Use this page to detail your site's privacy policy.</p>
<h2>
MyRoot:MyParent:MyChildName: @Configuration["MyRoot:MyParent:MyChildName"]
</h2>
詳細については、「ASP.NET Core の構成」を参照してください
@inject
ディレクティブを使用して、サービスをビューに挿入することができます。
@using System.Threading.Tasks
@using ViewInjectSample.Model
@using ViewInjectSample.Model.Services
@model IEnumerable<ToDoItem>
@inject StatisticsService StatsService
<!DOCTYPE html>
<html>
<head>
<title>To Do Items</title>
</head>
<body>
<div>
<h1>To Do Items</h1>
<ul>
<li>Total Items: @StatsService.GetCount()</li>
<li>Completed: @StatsService.GetCompletedCount()</li>
<li>Avg. Priority: @StatsService.GetAveragePriority()</li>
</ul>
<table>
<tr>
<th>Name</th>
<th>Priority</th>
<th>Is Done?</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.Priority</td>
<td>@item.IsDone</td>
</tr>
}
</table>
</div>
</body>
</html>
このビューでは、全体的な統計を示す概要と共に、ToDoItem
インスタンスのリストが表示されます。 概要は、挿入された StatisticsService
から作成されます。 このサービスは、ConfigureServices
内の Program.cs
の依存関係の挿入に登録されます:
using ViewInjectSample.Helpers;
using ViewInjectSample.Infrastructure;
using ViewInjectSample.Interfaces;
using ViewInjectSample.Model.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddTransient<IToDoItemRepository, ToDoItemRepository>();
builder.Services.AddTransient<StatisticsService>();
builder.Services.AddTransient<ProfileOptionsService>();
builder.Services.AddTransient<MyHtmlHelper>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
StatisticsService
では、ToDoItem
インスタンスのセットでいくつかの計算を実行します。これには、次のリポジトリを使用してアクセスします。
using System.Linq;
using ViewInjectSample.Interfaces;
namespace ViewInjectSample.Model.Services
{
public class StatisticsService
{
private readonly IToDoItemRepository _toDoItemRepository;
public StatisticsService(IToDoItemRepository toDoItemRepository)
{
_toDoItemRepository = toDoItemRepository;
}
public int GetCount()
{
return _toDoItemRepository.List().Count();
}
public int GetCompletedCount()
{
return _toDoItemRepository.List().Count(x => x.IsDone);
}
public double GetAveragePriority()
{
if (_toDoItemRepository.List().Count() == 0)
{
return 0.0;
}
return _toDoItemRepository.List().Average(x => x.Priority);
}
}
}
サンプルのリポジトリでは、メモリ内のコレクションを使用します。 メモリ内実装は、リモートからアクセスされる大規模なデータ セットには使用しないでください。
サンプルには、ビューとビューに挿入されたサービスにバインドされたモデルからのデータが表示されています。
ビューの挿入は、ドロップダウン リストなど、UI 要素のオプションの作成に役立ちます。 性別、状態、およびその他の基本設定を指定するオプションを含む、ユーザー プロファイル フォームを検討します。 標準のアプローチを使用してこのようなフォームをレンダリングするには、コントローラーまたは Razor Page で次の操作を行う必要があります:
ViewBag
を自動入力します。別のアプローチでは、オプションを取得するために、ビューに直接サービスを挿入します。 これにより、コントローラーまたは Razor ページに必要なコードの量が最小限に抑えられます。これにより、このビュー要素の構築ロジックがビュー自体に移動されます。 プロファイルの編集フォームを表示するコントローラー アクションまたは Razor Page は、フォームにプロファイル インスタンスを渡すためにのみ必要です:
using Microsoft.AspNetCore.Mvc;
using ViewInjectSample.Model;
namespace ViewInjectSample.Controllers;
public class ProfileController : Controller
{
public IActionResult Index()
{
// A real app would up profile based on the user.
var profile = new Profile()
{
Name = "Rick",
FavColor = "Blue",
Gender = "Male",
State = new State("Ohio","OH")
};
return View(profile);
}
}
これらの基本設定を更新するために使用される HTML フォームには、3 つのプロパティのドロップダウン リストが含まれます:
これらのリストは、ビューに挿入されたサービスによって作成されます。
@using System.Threading.Tasks
@using ViewInjectSample.Model.Services
@model ViewInjectSample.Model.Profile
@inject ProfileOptionsService Options
<!DOCTYPE html>
<html>
<head>
<title>Update Profile</title>
</head>
<body>
<div>
<h1>Update Profile</h1>
Name: @Html.TextBoxFor(m => m.Name)
<br/>
Gender: @Html.DropDownList("Gender",
Options.ListGenders().Select(g =>
new SelectListItem() { Text = g, Value = g }))
<br/>
State: @Html.DropDownListFor(m => m.State!.Code,
Options.ListStates().Select(s =>
new SelectListItem() { Text = s.Name, Value = s.Code}))
<br />
Fav. Color: @Html.DropDownList("FavColor",
Options.ListColors().Select(c =>
new SelectListItem() { Text = c, Value = c }))
</div>
</body>
</html>
ProfileOptionsService
は、このフォームに必要なデータだけを提供する UI レベルのサービスです。
namespace ViewInjectSample.Model.Services;
public class ProfileOptionsService
{
public List<string> ListGenders()
{
// Basic sample
return new List<string>() {"Female", "Male"};
}
public List<State> ListStates()
{
// Add a few states
return new List<State>()
{
new State("Alabama", "AL"),
new State("Alaska", "AK"),
new State("Ohio", "OH")
};
}
public List<string> ListColors()
{
return new List<string>() { "Blue","Green","Red","Yellow" };
}
}
サービス プロバイダーは GetRequiredService を介して内部的にクエリが実行されるため、未登録の型は実行時に例外をスローすることに注意してください。
新しいサービスを挿入するだけでなく、この技術はページ上の以前に挿入されたサービスをオーバーライドするためにも使用できます。 以下の図は、最初の例で使用されたページで利用できるすべてのフィールドを示しています。
既定のフィールドには、Html
、Component
、および Url
が含まれます。 既定の HTML ヘルパーをカスタム バージョンに置き換えるには、@inject
を使用します:
@using System.Threading.Tasks
@using ViewInjectSample.Helpers
@inject MyHtmlHelper Html
<!DOCTYPE html>
<html>
<head>
<title>My Helper</title>
</head>
<body>
<div>
Test: @Html.Value
</div>
</body>
</html>
ASP.NET Core では、ビューへの依存関係の挿入をサポートしています。 この機能は、ビュー要素を作成するためだけに必要なローカライズやデータなど、ビュー固有のサービスに役立ちます。 コントローラーとビューの間で関心の分離を保持する必要があります。 ビューに表示されるデータのほとんどは、コントローラーから渡されます。
サンプル コードを表示またはダウンロードします (ダウンロード方法)。
appsettings.json
値は、ビューに直接挿入できます。
appsettings.json
ファイルの例:
{
"root": {
"parent": {
"child": "myvalue"
}
}
}
@inject
: @inject <type> <name>
の構文
@inject
を使用した例:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
@{
string myValue = Configuration["root:parent:child"];
...
}
@inject
ディレクティブを使用して、サービスをビューに挿入することができます。 @inject
は、ビューにプロパティを追加したり、DI を使用してプロパティを設定したりするものと考えることができます。
@using System.Threading.Tasks
@using ViewInjectSample.Model
@using ViewInjectSample.Model.Services
@model IEnumerable<ToDoItem>
@inject StatisticsService StatsService
<!DOCTYPE html>
<html>
<head>
<title>To Do Items</title>
</head>
<body>
<div>
<h1>To Do Items</h1>
<ul>
<li>Total Items: @StatsService.GetCount()</li>
<li>Completed: @StatsService.GetCompletedCount()</li>
<li>Avg. Priority: @StatsService.GetAveragePriority()</li>
</ul>
<table>
<tr>
<th>Name</th>
<th>Priority</th>
<th>Is Done?</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.Priority</td>
<td>@item.IsDone</td>
</tr>
}
</table>
</div>
</body>
</html>
このビューでは、全体的な統計を示す概要と共に、ToDoItem
インスタンスのリストが表示されます。 概要は、挿入された StatisticsService
から作成されます。 このサービスは、ConfigureServices
内の Startup.cs
の依存関係の挿入に登録されます:
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
StatisticsService
では、ToDoItem
インスタンスのセットでいくつかの計算を実行します。これには、次のリポジトリを使用してアクセスします。
using System.Linq;
using ViewInjectSample.Interfaces;
namespace ViewInjectSample.Model.Services
{
public class StatisticsService
{
private readonly IToDoItemRepository _toDoItemRepository;
public StatisticsService(IToDoItemRepository toDoItemRepository)
{
_toDoItemRepository = toDoItemRepository;
}
public int GetCount()
{
return _toDoItemRepository.List().Count();
}
public int GetCompletedCount()
{
return _toDoItemRepository.List().Count(x => x.IsDone);
}
public double GetAveragePriority()
{
if (_toDoItemRepository.List().Count() == 0)
{
return 0.0;
}
return _toDoItemRepository.List().Average(x => x.Priority);
}
}
}
サンプルのリポジトリでは、メモリ内のコレクションを使用します。 上記の (メモリ内のすべてのデータを操作する) 実装は、大規模なリモートでアクセスされるデータ セットにはお勧めしません。
サンプルには、ビューとビューに挿入されたサービスにバインドされたモデルからのデータが表示されています。
ビューの挿入は、ドロップダウン リストなど、UI 要素のオプションの作成に役立ちます。 性別、状態、およびその他の基本設定を指定するオプションを含む、ユーザー プロファイル フォームを検討します。 標準の MVC アプローチを使用するフォームのようなレンダリングには、これらのオプションのセットごとにデータ アクセス サービスを要求し、バインドするオプションの各セットを含むモデルまたは ViewBag
を作成するために、コントローラーが必要です。
別のアプローチでは、オプションを取得するために、ビューに直接サービスを挿入します。 これにより、このビュー要素の構築ロジックをビュー自体に移動して、コントローラーから要求されるコードの量を最小限にします。 プロファイルの編集フォームを表示するコントローラー アクションは、フォームにプロファイル インスタンスを渡すためにのみ必要です。
using Microsoft.AspNetCore.Mvc;
using ViewInjectSample.Model;
namespace ViewInjectSample.Controllers
{
public class ProfileController : Controller
{
[Route("Profile")]
public IActionResult Index()
{
// TODO: look up profile based on logged-in user
var profile = new Profile()
{
Name = "Steve",
FavColor = "Blue",
Gender = "Male",
State = new State("Ohio","OH")
};
return View(profile);
}
}
}
これらの基本設定を更新するために使用される HTML フォームには、3 つのプロパティのドロップダウン リストが含まれます。
これらのリストは、ビューに挿入されたサービスによって作成されます。
@using System.Threading.Tasks
@using ViewInjectSample.Model.Services
@model ViewInjectSample.Model.Profile
@inject ProfileOptionsService Options
<!DOCTYPE html>
<html>
<head>
<title>Update Profile</title>
</head>
<body>
<div>
<h1>Update Profile</h1>
Name: @Html.TextBoxFor(m => m.Name)
<br/>
Gender: @Html.DropDownList("Gender",
Options.ListGenders().Select(g =>
new SelectListItem() { Text = g, Value = g }))
<br/>
State: @Html.DropDownListFor(m => m.State.Code,
Options.ListStates().Select(s =>
new SelectListItem() { Text = s.Name, Value = s.Code}))
<br />
Fav. Color: @Html.DropDownList("FavColor",
Options.ListColors().Select(c =>
new SelectListItem() { Text = c, Value = c }))
</div>
</body>
</html>
ProfileOptionsService
は、このフォームに必要なデータだけを提供する UI レベルのサービスです。
using System.Collections.Generic;
namespace ViewInjectSample.Model.Services
{
public class ProfileOptionsService
{
public List<string> ListGenders()
{
// keeping this simple
return new List<string>() {"Female", "Male"};
}
public List<State> ListStates()
{
// a few states from USA
return new List<State>()
{
new State("Alabama", "AL"),
new State("Alaska", "AK"),
new State("Ohio", "OH")
};
}
public List<string> ListColors()
{
return new List<string>() { "Blue","Green","Red","Yellow" };
}
}
}
重要
Startup.ConfigureServices
での依存関係の挿入を介して要求する型を登録するのを忘れないでください。 サービス プロバイダーは GetRequiredService を介して内部的にクエリが実行されるため、未登録の型は実行時に例外をスローします。
新しいサービスを挿入するだけでなく、この技術はページ上の以前に挿入されたサービスをオーバーライドするためにも使用できます。 以下の図は、最初の例で使用されたページで利用できるすべてのフィールドを示しています。
ご覧のように、既定のフィールドには、Html
、Component
、Url
(さらに、挿入した StatsService
) が含まれます。 たとえば、既定の HTML ヘルパーを自分のヘルパーに置き換える場合は、@inject
を使用して簡単に置き換えることができます。
@using System.Threading.Tasks
@using ViewInjectSample.Helpers
@inject MyHtmlHelper Html
<!DOCTYPE html>
<html>
<head>
<title>My Helper</title>
</head>
<body>
<div>
Test: @Html.Value
</div>
</body>
</html>
既存のサービスを拡張する場合、独自に既存の実装から継承したり、ラップしたりするときに、この技術を使用できます。
ASP.NET Core に関するフィードバック
ASP.NET Core はオープンソース プロジェクトです。 フィードバックを提供するにはリンクを選択します。
トレーニング
モジュール
ASP.NET Core で依存関係の挿入を使用してサービスを構成する - Training
ASP.NET Core アプリの依存関係の挿入を理解して実装します。 ASP.NET Core の組み込みのサービス コンテナーを使用して依存関係を管理します。 サービスをサービス コンテナーに登録します。
ドキュメント
区分は ASP.NET MVC の機能であり、関連する機能を別の名前空間 (ルーティングの場合) およびフォルダー構造 (ビューの場合) としてグループにまとめるために使用する方法を説明します。
部分ビューを使用して大規模なマークアップ ファイルを分割し、ASP.NET Core アプリの Web ページ間で共通するマークアップの重複を減らす方法について説明します。
ASP.NET Core MVC でコントローラーで要求を処理する
ASP.NET Core MVC コントローラーとアクションがどのように要求を処理し、応答を返すかについて説明します。