原文:Dependency injection into views

作者:Steve Smith

翻译:姚阿勇(Dr.Yao)

校对:孟帅洋(书缘)

ASP.NET Core 支持在视图中使用 依赖注入 。这将有助于提供视图专用的服务,比如本地化或者仅用于填充视图元素的数据。你应该尽量保持控制器和视图间的关注点分离(separation of concerns)。你的视图所显示的大部分数据应该从控制器传入。

章节:

查看或下载示例源码

一个简单的示例

你可以使用 @inject 指令将服务注入到视图中。可以把 @inject 看作是给你的视图增加一个属性,然后利用依赖注入给这个属性赋值。

@inject 的语法:

@inject <type> <name>

一个使用 @inject 的例子:

  1. @using System.Threading.Tasks
  2. @using ViewInjectSample.Model
  3. @using ViewInjectSample.Model.Services
  4. @model IEnumerable<ToDoItem>
  5. @inject StatisticsService StatsService
  6. <!DOCTYPE html>
  7. <html>
  8. <head>
  9. <title>To Do Items</title>
  10. </head>
  11. <body>
  12. <div>
  13. <h1>To Do Items</h1>
  14. <ul>
  15. <li>Total Items: @StatsService.GetCount()</li>
  16. <li>Completed: @StatsService.GetCompletedCount()</li>
  17. <li>Avg. Priority: @StatsService.GetAveragePriority()</li>
  18. </ul>
  19. <table>
  20. <tr>
  21. <th>Name</th>
  22. <th>Priority</th>
  23. <th>Is Done?</th>
  24. </tr>
  25. @foreach (var item in Model)
  26. {
  27. <tr>
  28. <td>@item.Name</td>
  29. <td>@item.Priority</td>
  30. <td>@item.IsDone</td>
  31. </tr>
  32. }
  33. </table>
  34. </div>
  35. </body>
  36. </html>

这个视图显示了一个 ToDoItem 实例的列表和统计概览。概览信息是由注入的服务 StatisticsService 填入的。这个服务是在 Startup.cs 里的 ConfigureServices 方法中被注册到依赖注入项的。

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

StatisticsService 对通过仓储读取到的 ToDoItem 数据集执行一些计算。

  1. using System.Linq;
  2. using ViewInjectSample.Interfaces;
  3. namespace ViewInjectSample.Model.Services
  4. {
  5. public class StatisticsService
  6. {
  7. private readonly IToDoItemRepository _toDoItemRepository;
  8. public StatisticsService(IToDoItemRepository toDoItemRepository)
  9. {
  10. _toDoItemRepository = toDoItemRepository;
  11. }
  12. public int GetCount()
  13. {
  14. return _toDoItemRepository.List().Count();
  15. }
  16. public int GetCompletedCount()
  17. {
  18. return _toDoItemRepository.List().Count(x => x.IsDone);
  19. }
  20. public double GetAveragePriority()
  21. {
  22. if (_toDoItemRepository.List().Count() == 0)
  23. {
  24. return 0.0;
  25. }
  26. return _toDoItemRepository.List().Average(x => x.Priority);
  27. }
  28. }
  29. }

示例中的仓储使用的是 in-memory 集合。上面的实现方法(所有对内存数据的操作)不推荐用于大型、远程存储的数据集。

这个示例通过绑定到视图的模型以及注入到视图的服务来显示数据:

填充查找数据

视图注入有助于填充 UI 元素中的选项数据,例如下拉列表。设想一个包括性别、州以及其他选项的用户资料表单。如果通过标准的 MVC 方式渲染这样一个表单,需要控制器为每一组选项都请求数据访问服务,然后将每一组待绑定的选项填充到模型或 ViewBag 中。

另一种方法则直接将服务注入到视图中以获取这些选项数据。这种方法将控制器需要的代码量减到了最少,把构造视图元素的逻辑移到视图本身中去。用来显示资料编辑表单的控制器 Action 只需要把用户资料实例传给表格就可以了(而不需要传各种选项数据,译注):

  1. using Microsoft.AspNetCore.Mvc;
  2. using ViewInjectSample.Model;
  3. namespace ViewInjectSample.Controllers
  4. {
  5. public class ProfileController : Controller
  6. {
  7. [Route("Profile")]
  8. public IActionResult Index()
  9. {
  10. // TODO: look up profile based on logged-in user
  11. var profile = new Profile()
  12. {
  13. Name = "Steve",
  14. FavColor = "Blue",
  15. Gender = "Male",
  16. State = new State("Ohio","OH")
  17. };
  18. return View(profile);
  19. }
  20. }
  21. }

用来编辑这些选项的 HTML 表单包含选项中的三个下拉列表:

这些列表是由注入到视图的一个服务填充的:

  1. @using System.Threading.Tasks
  2. @using ViewInjectSample.Model.Services
  3. @model ViewInjectSample.Model.Profile
  4. @inject ProfileOptionsService Options
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <title>Update Profile</title>
  9. </head>
  10. <body>
  11. <div>
  12. <h1>Update Profile</h1>
  13. Name: @Html.TextBoxFor(m => m.Name)
  14. <br/>
  15. Gender: @Html.DropDownList("Gender",
  16. Options.ListGenders().Select(g =>
  17. new SelectListItem() { Text = g, Value = g }))
  18. <br/>
  19. State: @Html.DropDownListFor(m => m.State.Code,
  20. Options.ListStates().Select(s =>
  21. new SelectListItem() { Text = s.Name, Value = s.Code}))
  22. <br />
  23. Fav. Color: @Html.DropDownList("FavColor",
  24. Options.ListColors().Select(c =>
  25. new SelectListItem() { Text = c, Value = c }))
  26. </div>
  27. </body>
  28. </html>

ProfileOptionsService 是一个 UI 层的服务,旨在为这个表单提供所需数据 :

  1. using System.Collections.Generic;
  2. namespace ViewInjectSample.Model.Services
  3. {
  4. public class ProfileOptionsService
  5. {
  6. public List<string> ListGenders()
  7. {
  8. // keeping this simple
  9. return new List<string>() {"Female", "Male"};
  10. }
  11. public List<State> ListStates()
  12. {
  13. // a few states from USA
  14. return new List<State>()
  15. {
  16. new State("Alabama", "AL"),
  17. new State("Alaska", "AK"),
  18. new State("Ohio", "OH")
  19. };
  20. }
  21. public List<string> ListColors()
  22. {
  23. return new List<string>() { "Blue","Green","Red","Yellow" };
  24. }
  25. }
  26. }

提示

不要忘记在 Startup.csConfigureServices 方法中把你想要通过依赖注入请求的类型注册一下。

重写服务

除了注入新服务之外,这种技术也可以用来重写之前已经在页面上注入的服务。下图显示了在第一个例子的页面上可用的所有字段:

如你所见,默认的字段有 HtmlComponentUrl (同样还有我们注入的 StatsService)。假如你想要把默认的 HTML Helpers 替换成你自己的,你可以利用 @inject 轻松实现:

  1. @using System.Threading.Tasks
  2. @using ViewInjectSample.Helpers
  3. @inject MyHtmlHelper Html
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <title>My Helper</title>
  8. </head>
  9. <body>
  10. <div>
  11. Test: @Html.Value
  12. </div>
  13. </body>
  14. </html>

如果你想要扩展已有服务,你只需要在使用这种替换技术的同时,让你自己的服务继承或封装已有实现。

参考

返回目录

ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入的更多相关文章

  1. ASP.NET Core 中文文档 第四章 MVC(3.1)视图概述

    原文:Views Overview 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:高嵩(Jack) ASP.NET MVC Core 的控制器可以利用 视图 返回格式化结果. 什么 ...

  2. ASP.NET Core 中文文档 第四章 MVC(4.2)控制器操作的路由

    原文:Routing to Controller Actions 作者:Ryan Nowak.Rick Anderson 翻译:娄宇(Lyrics) 校对:何镇汐.姚阿勇(Dr.Yao) ASP.NE ...

  3. ASP.NET Core 中文文档 第四章 MVC(3.6.1 )Tag Helpers 介绍

    原文:Introduction to Tag Helpers 作者:Rick Anderson 翻译:刘浩杨 校对:高嵩(Jack) 什么是 Tag Helpers? Tag Helpers 提供了什 ...

  4. ASP.NET Core 中文文档 第四章 MVC(4.6)Areas(区域)

    原文:Areas 作者:Dhananjay Kumar 和 Rick Anderson 翻译:耿晓亮(Blue) 校对:许登洋(Seay) Areas 是 ASP.NET MVC 用来将相关功能组织成 ...

  5. ASP.NET Core 中文文档 第四章 MVC(4.5)测试控制器逻辑

    原文: Testing Controller Logic 作者: Steve Smith 翻译: 姚阿勇(Dr.Yao) 校对: 高嵩(Jack) ASP.NET MVC 应用程序的控制器应当小巧并专 ...

  6. ASP.NET Core 中文文档 第四章 MVC(4.4)依赖注入和控制器

    原文: Dependency Injection and Controllers 作者: Steve Smith 翻译: 刘浩杨 校对: 孟帅洋(书缘) ASP.NET Core MVC 控制器应通过 ...

  7. ASP.NET Core 中文文档 第四章 MVC(4.1)Controllers, Actions 和 Action Results

    原文:Controllers, Actions, and Action Results 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:许登洋(Seay) Action 和 acti ...

  8. ASP.NET Core 中文文档 第四章 MVC(3.9)视图组件

    作者: Rick Anderson 翻译: 娄宇(Lyrics) 校对: 高嵩 章节: 介绍视图组件 创建视图组件 调用视图组件 演练:创建一个简单的视图组件 附加的资源 查看或下载示例代码 介绍视图 ...

  9. ASP.NET Core 中文文档 第四章 MVC(3.7 )局部视图(partial)

    原文:Partial Views 作者:Steve Smith 翻译:张海龙(jiechen).刘怡(AlexLEWIS) 校对:许登洋(Seay).何镇汐.魏美娟(初见) ASP.NET Core ...

随机推荐

  1. 常用 Gulp 插件汇总 —— 基于 Gulp 的前端集成解决方案(三)

    前两篇文章讨论了 Gulp 的安装部署及基本概念,借助于 Gulp 强大的 插件生态 可以完成很多常见的和不常见的任务.本文主要汇总常用的 Gulp 插件及其基本使用,需要读者对 Gulp 有一个基本 ...

  2. Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...

  3. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  4. C++ std::set

    std::set template < class T, // set::key_type/value_type class Compare = less<T>, // set::k ...

  5. requests的content与text导致lxml的解析问题

    title: requests的content与text导致lxml的解析问题 date: 2015-04-29 22:49:31 categories: 经验 tags: [Python,lxml, ...

  6. Node.js:dgram模块实现UDP通信

    1.什么是UDP? 这里简单介绍下,UDP,即用户数据报协议,一种面向无连接的传输层协议,提供不可靠的消息传送服务.UDP协议使用端口号为不同的应用保留其各自的数据传输通道,这一点非常重要.与TCP相 ...

  7. Mysql存储引擎及选择方法

    0x00 Mysql数据库常用存储引擎 Mysql数据库是一款开源的数据库,支持多种存储引擎的选择,比如目前最常用的存储引擎有:MyISAM,InnoDB,Memory等. MyISAM存储引擎 My ...

  8. Linux杀死进程,查看进程

    http://blog.csdn.net/wojiaopanpan/article/details/7286430/

  9. Android中Activity的四大启动模式实验简述

    作为Android四大组件之一,Activity可以说是最基本也是最常见的组件,它提供了一个显示界面,从而实现与用户的交互,作为初学者,必须熟练掌握.今天我们就来通过实验演示,来帮助大家理解Activ ...

  10. Mysql 忘记root密码处理办法

    一.更改my.cnf配置文件 1.用命令编辑/etc/my.cnf配置文件,即:vim /etc/my.cnf 或者 vi /etc/my.cnf 2.在[mysqld]下添加skip-grant-t ...