Megosztás a következőn keresztül:


Függőségi injektálás a ASP.NET Core nézeteibe

ASP.NET Core támogatja függőséginjektálást nézetekbe. Ez olyan nézethez kötődő szolgáltatások esetében lehet hasznos, mint például a honosítás vagy a csak a nézetelemek feltöltéséhez szükséges adatok. A megjelenített adatnézetek többségét át kell adni a vezérlőből.

Mintakód megtekintése vagy letöltése (letöltési útmutató)

Konfigurációs injektálás

A beállításfájlokban lévő értékek( például appsettings.json és appsettings.Development.json) beszúrhatók egy nézetbe. Vegye figyelembe a appsettings.Development.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "MyRoot": {
    "MyParent": {
      "MyChildName": "Joe"
    }
  }
}

Az alábbi jelölőnyelv a konfigurációs értéket a Razor Lapok nézetben jeleníti meg:

@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>

Az alábbi korrektúra MVC nézetben jeleníti meg a konfigurációs értéket:

@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>

Lásd a(z) ASP.NET Core konfigurációt a további információkért.

Szolgáltatásinjektálás

A szolgáltatás a @inject irányelvvel helyezhető be egy nézetbe.

@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>

Ez a nézet megjeleníti a ToDoItem példányok listáját, valamint az általános statisztikákat bemutató összegzést. Az összegzés a beszúrt StatisticsServicealapján készül. Ez a szolgáltatás regisztrálva van a függőséginjektáláshoz a ConfigureServices-ban, illetve Program.cs-ben.

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();

A StatisticsService végrehajt néhány számítást a ToDoItem példányok készletén, amelyeket egy adattáron keresztül ér el:

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);
        }
    }
}

A mintaadattár egy memóriabeli gyűjteményt használ. A memórián belüli implementáció nem használható nagy, távolról elérhető adathalmazokhoz.

A minta a nézethez kötött modell és a nézetbe injektált szolgáltatás adatait jeleníti meg:

Teendők áttekintése, amely tartalmazza az összes tételt, a befejezett tételeket, az átlagos prioritást, valamint a feladatok listáját a prioritási szintekkel és a befejezést jelző logikai értékekkel.

Keresőlista adatok betöltése

A nézet injektálása hasznos lehet a felhasználói felület elemeinek, például a legördülő listáknak a kitöltéséhez. Fontolja meg a felhasználói profil űrlapot, amely a nemek, az állapot és az egyéb beállítások megadására szolgáló lehetőségeket tartalmaz. Ha egy ilyen űrlapot szabványos módszerrel jelenít meg, a vezérlőnek vagy Razor Oldalnak a következőkre lehet szüksége:

  • Adathozzáférési szolgáltatások kérése az egyes beállításkészletekhez.
  • Töltse ki a modellt vagy a ViewBag-t a hozzá rendelt beállítások mindegyikével.

Egy alternatív megközelítés közvetlenül a nézetbe tölti be a szolgáltatásokat az opciók eléréséhez. Ez minimalizálja a vezérlő vagy a Razor oldal által igényelt kód mennyiségét, a nézeti elem építési logikáját pedig magába a nézetbe helyezi át. A profilszerkesztő űrlap megjelenítéséhez szükséges vezérlőműveletnek vagy Razor lapnak csak a profilpéldánynak kell átadnia az űrlapot:

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);
    }
}

A beállítások frissítéséhez használt HTML-űrlap három tulajdonság legördülő listáját tartalmazza:

Profil nézet frissítése olyan űrlappal, amely lehetővé teszi a név, a nem, az állapot és a kedvenc szín bevitelét.

Ezeket a listákat egy, a nézetbe injektált szolgáltatás tölti ki:

@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>

A ProfileOptionsService egy felhasználói felületi szintű szolgáltatás, amely az űrlaphoz szükséges adatok megadására szolgál:

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" };
    }
}

Vegye figyelembe, hogy egy nem regisztrált típus kivételt dob futásidőben, mert a szolgáltató belső lekérdezést hajt végre a GetRequiredService keresztül.

Felülkondírozási szolgáltatások

Az új szolgáltatások injektálása mellett ezzel a technikával felülbírálhatja a korábban beszúrt szolgáltatásokat egy oldalon. Az alábbi ábrán az első példában használt lapon elérhető összes mező látható:

A beírt @ szimbólumra megjelenő Intellisense helyi menü HTML, összetevő, StatsService és URL mezőket listáz

Az alapértelmezett mezők közé tartozik a Html, a Componentés a Url. Ha az alapértelmezett HTML-segédeket egyéni verzióra szeretné cserélni, használja a @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>

Lásd még:

ASP.NET Core támogatja függőséginjektálást nézetekbe. Ez olyan nézethez kötődő szolgáltatások esetében lehet hasznos, mint például a honosítás vagy a csak a nézetelemek feltöltéséhez szükséges adatok. Próbálja meg fenntartani a vezérlők és a nézetek közötti felelősségek elkülönítését. A nézetek által megjelenített adatok többségét a vezérlőtől kell átadni.

Mintakód megtekintése vagy letöltése (letöltési útmutató)

Konfigurációs injektálás

appsettings.json értékek közvetlenül beszúrhatók egy nézetbe.

Példa egy appsettings.json fájlra:

{
   "root": {
      "parent": {
         "child": "myvalue"
      }
   }
}

A @injectszintaxisa: @inject <type> <name>

Egy példa @inject:

@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration
@{
   string myValue = Configuration["root:parent:child"];
   ...
}

Szolgáltatásinjektálás

A szolgáltatás a @inject irányelvvel helyezhető be egy nézetbe. Úgy tekinthetünk a(z) @inject-re, mint ha egy tulajdonságot adnánk a nézethez, és a tulajdonságot DI használatával töltenénk fel.

@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>

Ez a nézet megjeleníti a ToDoItem példányok listáját, valamint az általános statisztikákat bemutató összegzést. Az összegzés a beszúrt StatisticsServicealapján készül. Ez a szolgáltatás regisztrálva van a függőséginjektáláshoz a ConfigureServices-ban, illetve Startup.cs-ben.

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();

A StatisticsService végrehajt néhány számítást a ToDoItem példányok készletén, amelyeket egy adattáron keresztül ér el:

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);
        }
    }
}

A mintaadattár egy memóriabeli gyűjteményt használ. A fenti implementáció (amely a memóriában lévő összes adaton működik) nem ajánlott nagy, távolról elérhető adatkészletekhez.

A minta a nézethez kötött modell és a nézetbe injektált szolgáltatás adatait jeleníti meg:

Teendők áttekintése, amely tartalmazza az összes tételt, a befejezett tételeket, az átlagos prioritást, valamint a feladatok listáját a prioritási szintekkel és a befejezést jelző logikai értékekkel.

Keresőlista adatok betöltése

A nézet injektálása hasznos lehet a felhasználói felület elemeinek, például a legördülő listáknak a kitöltéséhez. Fontolja meg a felhasználói profil űrlapot, amely a nemek, az állapot és az egyéb beállítások megadására szolgáló lehetőségeket tartalmaz. Ha egy ilyen űrlapot szabványos MVC-módszerrel jelenít meg, a vezérlőnek adatelérési szolgáltatásokat kell kérnie ezekhez a beállításokhoz, majd fel kell töltenie egy modellt vagy ViewBag az egyes beállításkészletekkel.

Egy alternatív megközelítés közvetlenül a nézetbe tölti be a szolgáltatásokat az opciók eléréséhez. Ez minimalizálja a vezérlő által igényelt kód mennyiségét, és ezt a nézetelem-építési logikát magára a nézetre helyezi át. A profilszerkesztő űrlap megjelenítéséhez szükséges vezérlőműveletnek csak a profilpéldánynak kell átadnia az űrlapot:

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);
        }
    }
}

A beállítások frissítéséhez használt HTML-űrlap három tulajdonság legördülő listáját tartalmazza:

Profil nézet frissítése olyan űrlappal, amely lehetővé teszi a név, a nem, az állapot és a kedvenc szín bevitelét.

Ezeket a listákat egy, a nézetbe injektált szolgáltatás tölti ki:

@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>

A ProfileOptionsService egy felhasználói felületi szintű szolgáltatás, amely az űrlaphoz szükséges adatok megadására szolgál:

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" };
        }
    }
}

Important

Ne felejtse el regisztrálni a függőséginjektálással kért típusokat a Startup.ConfigureServices-ban. A nem regisztrált típus kivételt jelent futásidőben, mert a szolgáltató belső lekérdezése GetRequiredServicekeresztül történik.

Felülkondírozási szolgáltatások

Az új szolgáltatások injektálása mellett ez a technika a korábban beszúrt szolgáltatások felülbírálására is használható az oldalon. Az alábbi ábrán az első példában használt lapon elérhető összes mező látható:

A beírt @ szimbólumra megjelenő Intellisense helyi menü HTML, összetevő, StatsService és URL mezőket listáz

Mint látható, az alapértelmezett mezők közé tartozik a Html, a Componentés a Url (valamint a beszúrt StatsService). Ha például az alapértelmezett HTML-segédosztályokat sajátjaikra szeretné cserélni, ezt egyszerűen megteheti @injecthasználatával.

@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>

Ha ki szeretné terjeszteni a meglévő szolgáltatásokat, egyszerűen használhatja ezt a technikát, miközben a meglévő implementációt a sajátjával örökli vagy burkolja.

Lásd még: