zoukankan      html  css  js  c++  java
  • ASP.NET Core之依赖注入

    本文翻译自: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 容器注册并在程序中使用。

     1   public interface ILog
     2   {
     3       void info(string str);
     4   }
     5 
     6   class MyConsoleLogger : ILog
     7   {
     8       public void info(string str)
     9       {
    10           Console.WriteLine(str);
    11       }
    12   }

     

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

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

    1   public class Startup
    2   {
    3       public void ConfigureServices(IServiceCollection services)
    4       {
    5           services.Add(new ServiceDescriptor(typeof(ILog), new MyConsoleLogger()));        
    6       }
    7 
    8       // other code removed for clarity.. 
    9   }

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

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

    服务的生命周期

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

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

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

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

    1 public void ConfigureServices(IServiceCollection services)
    2 {
    3     services.Add(new ServiceDescriptor(typeof(ILog), new MyConsoleLogger()));    // singleton
    4     
    5     services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Transient)); // Transient
    6     
    7     services.Add(new ServiceDescriptor(typeof(ILog), typeof(MyConsoleLogger), ServiceLifetime.Scoped));    // Scoped
    8 }

    注册的扩展方法

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

    使用扩展方法注册

     1 public void ConfigureServices(IServiceCollection services)
     2 {
     3     services.AddSingleton<ILog, MyConsoleLogger>();
     4     services.AddSingleton(typeof(ILog), typeof(MyConsoleLogger));
     5 
     6     services.AddTransient<ILog, MyConsoleLogger>();
     7     services.AddTransient(typeof(ILog), typeof(MyConsoleLogger));
     8 
     9     services.AddScoped<ILog, MyConsoleLogger>();
    10     services.AddScoped(typeof(ILog), typeof(MyConsoleLogger));
    11 }

    构造函数注入

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

     1 public class HomeController : Controller
     2 {
     3     ILog _log;
     4 
     5     public HomeController(ILog log)
     6     {
     7         _log = log;
     8     }
     9     public IActionResult Index()
    10     {
    11         _log.info("Executing /home/index");
    12 
    13         return View();
    14     }
    15 }

    上面的代码中,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属性手动的获取依赖服务。

     1 public class HomeController : Controller
     2 {
     3     public HomeController()
     4     {
     5     }
     6     public IActionResult Index()
     7     {
     8         var services = this.HttpContext.RequestServices;
     9         var log = (ILog)services.GetService(typeof(ILog));
    10             
    11         log.info("Index method executing");
    12     
    13         return View();
    14     }
    15 }

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

  • 相关阅读:
    JavaScript 基本类型值-Undefined、Null、Boolean
    Git学习之路(6)- 分支操作
    Git学习之路(5)- 同步到远程仓库及多人协作问题
    setTimeout小总结
    Git学习之路(4)- 撤销操作、删除文件和恢复文件
    Git学习之路(3)-提交文件到三个区
    Git学习之路(2)-安装GIt和创建版本库
    Git学习之路(1)-Git简介
    两种常见挂载Jenkins slave节点的方法
    rabbitmq集群节点操作
  • 原文地址:https://www.cnblogs.com/imstrive/p/10132815.html
Copyright © 2011-2022 走看看