本文翻译自:http://www.tutorialsteacher.com/core/dependency-injection-in-aspnet-core

ASP.NET Core支持依赖注入,依赖注入的对象通过构造函数或者 Ioc container 内置的方法进行注入。

内置的 IoC Container

ASP.NET Core框架包含了开箱即用的 Ioc容器,这个容器相比第三方的容器功能会有不足。如果想要更多例如 auto-registration、scanning、interceptors或者decorators那么可以使用第三方的容器替换内置的Ioc容器。

内置的容器是通过 IServiceProvider 接口的实现使用,默认支持构造函数注入。内置 Ioc容器管理的类称作 services。

在ASP.NET Core存在两种类型的服务:

  • 框架服务:服务是ASP.NET Core框架的一部分,比方说 IApplicationBuilder、IHostingEnvironment、ILoggerFactory等
  • 应用服务:由开发人员创建的服务(自定义的类型或者类)

为了使 Ioc容器自动注入应用服务,首先需要在Ioc容器注册。

注册应用服务

下面用简单的 ILog 接口以及它的显示举例来说明如何使用内置的 Ioc 容器注册并在程序中使用。

   public interface ILog
2 {
void info(string str);
} class MyConsoleLogger : ILog
{
public void info(string str)
{
Console.WriteLine(str);
}
}

ASP.NET Core允许我们在 ConfigureServices 方法中使用 Ioc 容器注册应用服务, ConfigureServices 包含了一个 IServiceCollection 类型的参数,该参数可以用于应用服务的注册。

下面在 ConfigureServices()方法中使用 Ioc 容器注册 ILog 接口。

   public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(ILog), new MyConsoleLogger()));
} 8 // other code removed for clarity..
}

如上所见, IServiceCollection实例的Add()方法用于 Ioc容器的服务注册。 ServiceDescriptor用于指定服务的类型和实例,此处指定 MyConsoleLogger作为 ILog服务的实例,此处默认是按照单利注册。

现在 Ioc容器可以创建一个 MyConsoleLogger类的单利对象,我们可以通过在类的构造函数包含 ILog或者方法参数包含 ILog实现在程序中的注入。

服务的生命周期

内置的 Ioc容器管理着已经注册的服务的生命周期,服务的实例会根据指定的生命周期自动的释放。

内置的 Ioc容器支持三种生命周期:

  • Singleton:Ioc容器创建在应用的整个证明周期创建并共享同一个实例
  • Transient:每次需要调用指定的服务的时候都会重新创建
  • Scoped   :在单词请求的过程中,IOC 容器对指定的服务创建一个实例。

不同的生命周期注册方法如下:

 public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(ILog), new MyConsoleLogger())); // singleton services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Transient)); // Transient services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Scoped)); // Scoped
}

注册的扩展方法

ASP.NET Core框架对于每种类型的生命周期都有对应的扩展方法:AddSingleton()AddTransient() 和 AddScoped()。

使用扩展方法注册

 public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ILog, MyConsoleLogger>();
services.AddSingleton(typeof(ILog), typeof(MyConsoleLogger)); services.AddTransient<ILog, MyConsoleLogger>();
services.AddTransient(typeof(ILog), typeof(MyConsoleLogger)); services.AddScoped<ILog, MyConsoleLogger>();
services.AddScoped(typeof(ILog), typeof(MyConsoleLogger));
}

构造函数注入

当我们注册一个服务时,如果构造函数包含某一类型的服务,该服务会被 IOC容器自动的注册。

 public class HomeController : Controller
{
ILog _log; public HomeController(ILog log)
{
_log = log;
}
public IActionResult Index()
{
_log.info("Executing /home/index"); return View();
}
}

上面的代码中,IOC容器自动的向HomeController的构造函数传递 MyConsoleLogger 的实例。这里不需要做额外的事情,IOC容器会根据注册的生命周期创建并释放 ILog的实例 。

Action方法注入

有时我们只是在单个的Action方法中需要依赖的服务,此时可以使用 [FromServices] 属性。

using Microsoft.AspNetCore.Mvc;

public class HomeController : Controller
{
public HomeController()
{
} public IActionResult Index([FromServices] ILog log)
{
log.info("Index method executing"); return View();
}
}

属性注入

内置的 IOC 容器并不支持属性注入,需要第三方的 IOC容器。

手动获取服务

属性注入不需要在构造函数包含依赖的方法。我们可以使用内置的IOC容器,使用HttpContext的RequestServices属性手动的获取依赖服务。

 public class HomeController : Controller
{
public HomeController()
{
}
public IActionResult Index()
{
var services = this.HttpContext.RequestServices;
var log = (ILog)services.GetService(typeof(ILog)); log.info("Index method executing"); return View();
}
}

推荐使用构造注入而非 RequestServices获取。

最新文章

  1. 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型
  2. spring mvc 请求转发和重定向(转)
  3. linux下使用远程图形界面
  4. fMRI数据分析处理原理及方法
  5. 后缀树(BZOJ3238TLE)
  6. 10.5.2 Boot Block 启动块 - 操作系统教程
  7. checkbox样式自定义
  8. android学习笔记二
  9. 四句话表明JSON格式定义
  10. HDU_2011——求多项式的前n项和
  11. 解析汽车B2C商城网站四种盈利模式
  12. 整理的 matplotlib 绘图笔记
  13. TP5 中实现支付宝支付 利用model层调用支付宝类库
  14. Java经典编程题50道之四十
  15. ZPW-2000电气绝缘移频轨道电路
  16. ROM、RAM、DRAM、SRAM和FLASH、PSRAM
  17. Scala中 =&gt; Unit 与 () =&gt;Unit的区别
  18. 正则表达式(Kotlin)
  19. c++中的类(class)-----笔记(类简介)
  20. Python基础语法-内置数据结构之列表

热门文章

  1. 如何基于Winform开发框架或混合框架基础上进行项目的快速开发
  2. Insertion Sort(Java)
  3. OC调用c++函数
  4. NIO原理及案例使用
  5. LeetCode-876 链表的中间结点
  6. springboot2.0整合shiro出现ShiroDialect报错 找不到org/thymeleaf/processor/attr/AbstractTextChildModifierAttrPr
  7. Java多线程处理某个线程超时的问题
  8. Nginx禁止IP直接访问网站
  9. Windows下Redis的安装和部署
  10. elastalert 配置post告警方式(备忘)