Injektáž závislostí do zobrazení v ASP.NET Core
ASP.NET Core podporuje injektáž závislostí do zobrazení. To může být užitečné pro služby specifické pro zobrazení, jako je lokalizace nebo data požadovaná pouze pro naplnění prvků zobrazení. Většina zobrazení dat by měla být předána ze kontroleru.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Injektáž konfigurace
Hodnoty v souborech nastavení, například appsettings.json
a appsettings.Development.json
, lze vložit do zobrazení. Podívejte se na appsettings.Development.json
ukázkový kód:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"MyRoot": {
"MyParent": {
"MyChildName": "Joe"
}
}
}
Následující kód zobrazí konfigurační hodnotu v Razor zobrazení Stránky:
@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>
Následující kód zobrazí konfigurační hodnotu v zobrazení 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>
Další informace najdete v tématu Konfigurace v ASP.NET Core
Injektáž služby
Službu lze vložit do zobrazení pomocí direktivy @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>
Toto zobrazení zobrazuje seznam ToDoItem
instancí spolu se souhrnem zobrazující celkové statistiky. Souhrn se vyplní ze vloženého StatisticsService
souboru . Tato služba je registrována pro injektáž závislostí v 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();
Provede StatisticsService
některé výpočty sady ToDoItem
instancí, ke kterým přistupuje prostřednictvím úložiště:
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);
}
}
}
Ukázkové úložiště používá kolekci v paměti. Implementace v paměti by neměla být použita pro velké a vzdáleně přístupné datové sady.
Ukázka zobrazí data z modelu vázaného na zobrazení a službu vloženou do zobrazení:
Naplnění vyhledávacích dat
Injektáž zobrazení může být užitečná k naplnění možností v prvech uživatelského rozhraní, jako jsou rozevírací seznamy. Představte si formulář profilu uživatele, který obsahuje možnosti pro určení pohlaví, stavu a dalších předvoleb. Vykreslení takového formuláře pomocí standardního přístupu může vyžadovat, aby kontroler nebo Razor stránka:
- Požádejte o služby pro přístup k datům pro každou sadu možností.
- Naplňte model nebo
ViewBag
každou sadu možností, které se mají svázat.
Alternativní přístup vloží služby přímo do zobrazení pro získání možností. Tím se minimalizuje množství kódu vyžadovaného kontrolerem nebo razor stránkou a přesune se tato logika konstrukce prvku zobrazení do samotného zobrazení. Akce kontroleru nebo Razor Stránka pro zobrazení formuláře pro úpravy profilu stačí předat pouze formulář instanci profilu:
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);
}
}
Formulář HTML použitý k aktualizaci předvoleb obsahuje rozevírací seznamy pro tři vlastnosti:
Tyto seznamy jsou naplněny službou, která byla vložena do zobrazení:
@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>
Jedná se ProfileOptionsService
o službu na úrovni uživatelského rozhraní navrženou tak, aby poskytovala pouze data potřebná pro tento formulář:
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" };
}
}
Všimněte si, že neregistrovaný typ vyvolá výjimku za běhu, protože poskytovatel služeb je interně dotazován prostřednictvím GetRequiredService.
Přepsání služeb
Kromě vkládání nových služeb lze tuto techniku použít k přepsání dříve vloženého služeb na stránce. Následující obrázek ukazuje všechna pole dostupná na stránce použité v prvním příkladu:
Výchozí pole zahrnují Html
, Component
a Url
. Chcete-li nahradit výchozí pomocné rutiny HTML vlastní verzí, použijte @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>
Viz také
- Simon Timms Blog: Získání vyhledávacích dat do vašeho zobrazení
ASP.NET Core podporuje injektáž závislostí do zobrazení. To může být užitečné pro služby specifické pro zobrazení, jako je lokalizace nebo data požadovaná pouze pro naplnění prvků zobrazení. Měli byste se pokusit zachovat oddělení obav mezi kontrolery a zobrazeními. Většina dat, která se zobrazí, by se měla předat ze kontroleru.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Injektáž konfigurace
appsettings.json
hodnoty lze vložit přímo do zobrazení.
appsettings.json
Příklad souboru:
{
"root": {
"parent": {
"child": "myvalue"
}
}
}
Syntaxe pro @inject
: @inject <type> <name>
Příklad použití @inject
:
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
@{
string myValue = Configuration["root:parent:child"];
...
}
Injektáž služby
Službu lze vložit do zobrazení pomocí direktivy @inject
. Můžete si představit @inject
přidání vlastnosti do zobrazení a naplnění vlastnosti pomocí 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>
Toto zobrazení zobrazuje seznam ToDoItem
instancí spolu se souhrnem zobrazující celkové statistiky. Souhrn se vyplní ze vloženého StatisticsService
souboru . Tato služba je registrována pro injektáž závislostí v 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();
Provede StatisticsService
některé výpočty sady ToDoItem
instancí, ke kterým přistupuje prostřednictvím úložiště:
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);
}
}
}
Ukázkové úložiště používá kolekci v paměti. Výše uvedená implementace (která pracuje se všemi daty v paměti) se nedoporučuje pro velké a vzdáleně přístupné datové sady.
Ukázka zobrazí data z modelu vázaného na zobrazení a službu vloženou do zobrazení:
Naplnění vyhledávacích dat
Injektáž zobrazení může být užitečná k naplnění možností v prvech uživatelského rozhraní, jako jsou rozevírací seznamy. Představte si formulář profilu uživatele, který obsahuje možnosti pro určení pohlaví, stavu a dalších předvoleb. Vykreslení takového formuláře pomocí standardního přístupu MVC by vyžadovalo, aby kontroler požádal o služby přístupu k datům pro každou z těchto sad možností a pak naplnil model nebo ViewBag
každou sadu možností, které mají být svázané.
Alternativní přístup vloží služby přímo do zobrazení pro získání možností. Tím se minimalizuje množství kódu vyžadovaného kontrolerem a přesune se tato logika konstrukce prvku zobrazení do samotného zobrazení. Akce kontroleru, která zobrazí formulář pro úpravy profilu, musí předat pouze formulář instanci profilu:
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);
}
}
}
Formulář HTML použitý k aktualizaci těchto předvoleb obsahuje rozevírací seznamy pro tři vlastnosti:
Tyto seznamy jsou naplněny službou, která byla vložena do zobrazení:
@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>
Jedná se ProfileOptionsService
o službu na úrovni uživatelského rozhraní navrženou tak, aby poskytovala pouze data potřebná pro tento formulář:
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" };
}
}
}
Důležité
Nezapomeňte zaregistrovat typy, které požadujete prostřednictvím injektáže závislostí .Startup.ConfigureServices
Neregistrovaný typ vyvolá výjimku za běhu, protože poskytovatel služeb je interně dotazován prostřednictvím GetRequiredService.
Přepsání služeb
Kromě vkládání nových služeb lze tuto techniku použít také k přepsání dříve vloženého služeb na stránce. Následující obrázek ukazuje všechna pole dostupná na stránce použité v prvním příkladu:
Jak můžete vidět, výchozí pole zahrnují Html
, Component
a Url
(stejně jako StatsService
vložené pole). Pokud byste například chtěli nahradit výchozí pomocné rutiny HTML vlastními, můžete to snadno provést pomocí @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>
Pokud chcete rozšířit stávající služby, můžete tuto techniku jednoduše použít při zdědění stávající implementace nebo zabalení vlastní implementace.
Viz také
- Simon Timms Blog: Získání vyhledávacích dat do vašeho zobrazení