ASP.NET Core MVC 控制器应通过构造函数明确地请求它们地依赖关系,在某些情况下,单个控制器地操作可能需要一个服务,在控制器级别上的请求可能没有意义。在这种情况下,也可以将服务作为  Action 的参数。

  依赖注入是一种如 Dependency Inversion Principle 所示的技术,允许应用程序松散耦合的模块组成。

1.构造函数注入

  ASP.NET Core 内置的基于构造函数的依赖注入支持扩展到 MVC 控制器。通过只添加一个服务类型作为构造函数参数到控制器中,ASP.NET Core 将会尝试使用内置服务容器解析这个类型。服务通常(但不总是)使用接口定义。例如,如果应用程序定义一个检索时间的服务,然后依赖注入而不是硬编码:

  定义接口和实现:

namespace MVCTest.Services
{
public interface IDateTime
{
DateTime Now { get; }
}
public class SystemDateTime: IDateTime
{
public DateTime Now
{
get { return DateTime.Now; }
}
}
}

  在 ConfigureServices 中注册服务到容器:

services.AddTransient<IDateTime, SystemDateTime>();

  在控制其中使用:

    public class DateTimeController : Controller
{
private IDateTime _dateTime;
public DateTimeController(IDateTime dateTime)
{
_dateTime = dateTime;
}
// GET: DateTime
public ActionResult Index()
{
var serverTime = _dateTime.Now;
if (serverTime.Hour < )
{
ViewData["Message"] = "Good Morning";
}
return View();
}
}

  ASP.NET Core 内置的依赖注入支持用于请求服务的类型只能有一个构造函数,如果多于一个会报异常。使用第三方实现替换默认依赖注入,可以实现支持多个构造函数。

2.使用 FromServices 操作注入

  有时,不需要在控制器为多个操作提供服务。在这种情况下,将服务注入到操作方法的参数是有意义的。通过 [FromServices] 标记参数来实现:

        public ActionResult Index([FromServices] IDateTime _dateTime)
{
var serverTime = _dateTime.Now;
if (serverTime.Hour < )
{
ViewData["Message"] = "Good Morning";
}
return View();
}

3.在控制器中访问设置

  在控制器中访问应用程序设置或者配置设置时常见的模式。此访问应当使用在 Configuration 中描述的访问模式。通常不应从控制器中使用依赖注入直接请求设置,更好的方式是请求 IOptions<T> 实例,T是你需要的配置类型。例如:

  创建选项类:

public class AppSettingOptions
{
public DefaultConnec ConnectionStrings { get; set; }
public string AllowedHosts { get; set; }
} public class DefaultConnec
{
public string DefaultConnection { get; set; }
}

appsettings.json:

{
"ConnectionStrings": {
"DefaultConnection": "Data Source=.;Initial Catalog=Test;Integrated Security=True"
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"AllowedHosts": "*"
}

  配置应用程序使用选项模型,在 ConfigureServices 中添加配置类到服务容器:

public Startup(IConfiguration configuration,IHostingEnvironment env)
{
//Configuration = configuration;
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json",optional:true,reloadOnChange:true)
//.AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional:true)
; //配置环境变量
//builder.AddEnvironmentVariables();
Configuration = builder.Build();
} public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettingOptions>(Configuration);
//通过代码编写
services.Configure<AppSettingOptions>(options=>
{
options.AllowedHosts = "test";
});
}

  示例是从 appsettings.json 读取设置,也可以在代码中添加设置。

  一旦指定了请类型的配置对象 AppSettingOptions,并将其添加到服务容器,就可以在控制器或操作方法通过请求 IOptions<AppSettingOptions>  的实例获取它:

    public class HomeController : Controller
{
private readonly IOptions<AppSettingOptions> _options;
public HomeController(IOptions<AppSettingOptions> options)
{
_options = options;
}
}

  遵循选项模式允许将设置和配置彼此分离,并且确保控制器遵循关注点分离,因为不需要知道如何在哪里找到设置信息。由于控制器类中没有静态附着或者直接实例化设置类,因此使得控制器更容易使用单元测试。

 

ASP.NET Core MVC 之依赖注入 Controller的更多相关文章

  1. ASP.NET Core MVC 之依赖注入 View

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

  2. ASP.NET Core中的依赖注入(1):控制反转(IoC)

    ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...

  3. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  4. ASP.NET Core 中的依赖注入

    目录 什么是依赖注入 ASP .NET Core 中使用依赖注入 注册 使用 释放 替换为其它的 Ioc 容器 参考 什么是依赖注入 软件设计原则中有一个依赖倒置原则(DIP),为了更好的解耦,讲究要 ...

  5. ASP.NET Core 中的 依赖注入介绍

    ASP.NET Core 依赖注入 HomeController public class HomeController : Controller { private IStudentReposito ...

  6. ASP.NET Core中的依赖注入(3): 服务的注册与提供

    在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core ...

  7. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

  8. ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【总体设计 】

    本系列前面的文章我们主要以编程的角度对ASP.NET Core的依赖注入系统进行了详细的介绍,如果读者朋友们对这些内容具有深刻的理解,我相信你们已经可以正确是使用这些与依赖注入相关的API了.如果你还 ...

  9. ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【解读ServiceCallSite 】

    通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的.ServiceProvider最 ...

随机推荐

  1. python接口自动化(三十四)-封装与调用--函数和参数化(详解)

    简介 前面虽然实现了参数的关联,但是那种只是记流水账的完成功能,不便于维护,也没什么可读性,随着水平和技能的提升,再返回头去看前边写的代码,简直是惨不忍睹那样的代码是初级入门的代码水平都达不到.接下来 ...

  2. 剑指offer第二版-总结:排序算法

    1.排序算法比较: 2.java实现 快排: /** * 快排 * * @since 2019年2月26日 下午1:37:34 * @author xuchao */ public class Qui ...

  3. WebRTC:数据传输相关协议简介

    对网络协议来说,需要做的通常就两件事情:1.建立连接,2.传输数据,WebRTC也不例外. 假设WebRTC应用的两端已经建立了连接,那么,剩下就是如何传输数据的问题了. WebRTC同时支持传输音视 ...

  4. akka 集群分片

    akka 集群 Sharding分片 分片上下级结构 集群(多台节点机) —> 每台节点机(1个片区) —> 每个片区(多个分片) —> 每个分片(多个实体) 实体: 分片管理的 A ...

  5. Java面试题汇总---整理版(附答案)

    今天继续为大家整理Java面试题,并涉及数据库和网络等相关知识,希望能帮助到各位开发者. 1,为什么要用spring,Spring主要使用了什么模式? spring能够很好的和各大框架整合,它通过IO ...

  6. VS2010 winform开发笔记---combox的SelectedIndexChanged事件及级联问题

    DisplayMember绑定需要显示的数据表字段, 而ValueMember绑定需要获取选择的项的值. 然后通过 combo.SelectedValue就可以取得选中项的值了. DisplayMem ...

  7. re模块:模式匹配与正则表达式

    一.用正则表达式查找文本模式 正则表达式,简称regex,是文本模式的描述方法.比如\d是一个正则表达式,用于表示一位0~9的数字.在一个模式后面加上花括号包围的数字n(如{n}),表示匹配这个模式n ...

  8. [leetcode] 134. Gas Station (medium)

    原题 题意: 过一个循环的加油站,每个加油站可以加一定数量的油,走到下一个加油站需要消耗一定数量的油,判断能否走一圈. 思路: 一开始思路就是遍历一圈,最直接的思路. class Solution { ...

  9. 解读Android MediaPlayer 详细使用方法

        MediaPlayer具有非常强大的功能,对音视频的播放均提供了支持,为了保证播放期间系统的正常工作,需要设置"android.permission.WAKE_LOCK"权 ...

  10. ThinkPHP5.0 模板

    ThinkPHP5.0 模板 模板渲染 默认的视图目录是默认的模块下的view目录 渲染规则:调用 \think\View 类fetch方法 // [模板文件目录]/当前控制器名(小写+下划线)/当前 ...