zoukankan      html  css  js  c++  java
  • 在 ASP.NET Core 中将依赖项注入到视图

    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 中填充。 在 Startup.cs 的 ConfigureServices 中为依赖关系注入注册此服务:

    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    
        services.AddTransient<IToDoItemRepository, ToDoItemRepository>();
        services.AddTransient<StatisticsService>();
        services.AddTransient<ProfileOptionsService>();

    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 窗体包括三个属性的下拉列表:

    这些列表由已注入视图的服务填充:

    @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 接受内部查询。

    替代服务

    除了注入新的服务之外,此方法也可用于替代以前在页面上注入的服务。 下图显示了第一个示例中使用的页面上的所有可用字段:

     如你所见,包括默认字段 HtmlComponent 和 Url(以及我们注入的 StatsService)。 如果想用自己的 HTML 帮助程序替换默认的 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>

    来自微软官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/views/dependency-injection?view=aspnetcore-6.0

  • 相关阅读:
    ACM-ICPC ShangHai 2014
    DEBUG感想
    WireShark 使用日记
    C++ 备忘录
    BZOJ 1022 [SHOI2008]小约翰的游戏John
    高斯消元
    BZOJ3236 [Ahoi2013]作业
    BZOJ P3293&&P1045
    ZKW费用流的理解
    BZOJ 几道水题 2014-4-22
  • 原文地址:https://www.cnblogs.com/djd66/p/15634866.html
Copyright © 2011-2022 走看看