原文:Dependency injection into views

作者:Steve Smith

翻译:姚阿勇(Dr.Yao)

校对:孟帅洋(书缘)

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

章节:

查看或下载示例源码

一个简单的示例

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

@inject 的语法:

@inject <type> <name>

一个使用 @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 填入的。这个服务是在 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);
}
}
}

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

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

填充查找数据

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

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

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.csConfigureServices 方法中把你想要通过依赖注入请求的类型注册一下。

重写服务

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

如你所见,默认的字段有 HtmlComponentUrl (同样还有我们注入的 StatsService)。假如你想要把默认的 HTML Helpers 替换成你自己的,你可以利用 @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 中文文档 第四章 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. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  2. ASP.NET Core HTTP 管道中的那些事儿

    前言 马上2016年就要过去了,时间可是真快啊. 上次写完 Identity 系列之后,反响还不错,所以本来打算写一个 ASP.NET Core 中间件系列的,但是中间遇到了很多事情.首先是 NPOI ...

  3. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  4. ABP教程-打造一个《电话簿项目》-目录-MPA版本-基于ABP1.13版本

    此系列文章会进行不定期的更新,应该会有6章左右. 感兴趣的朋友可以跟着看看,本教程适合已经看过ABP的文档但是又无从下手的小伙伴们. 初衷: 发布系列教程的原因是发现ABP在园子火了很久,但是发现还是 ...

  5. Winserver下的Hyper-v “未在远程桌面会话中捕获到鼠标”

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 服务器相关的知识点:http://www.cnblogs.com/dunitia ...

  6. .NET Core的日志[1]:采用统一的模式记录日志

    记录各种级别的日志是所有应用不可或缺的功能.关于日志记录的实现,我们有太多第三方框架可供选择,比如Log4Net.NLog.Loggr和Serilog 等,当然我们还可以选择微软原生的诊断框架(相关A ...

  7. 关于面试题 Array.indexof() 方法的实现及思考

    这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...

  8. javascript中变量提升的理解

    网上找了两个经典的例子 var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10 var ...

  9. 初识JavaScript

    JavaScript ECMA-262: 变量,函数,对象,数据类型....唯独没有输入和输出. Javascript:包含 ECMA-262,核心 BOM 浏览器对象模型, DOM 文档对象模型 什 ...

  10. 微软Visual Studio Code 0.8.0发布,新增多种主题

    月30日,Build 开发者大会上,正式宣布了 Visual Studio Code 项目;并将其定义为:一个运行于 Mac OS X.Windows和 Linux 之上的,针对于编写现代 Web 和 ...