架构师_程序员

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 379|回复: 0

[.NET Core] ASP.NET Core依赖注入使用自带的IOC容器

[复制链接]
跳转到指定楼层
楼主
发表于 2019-5-7 13:55:10
zu
ASP.NET Core依赖注入使用自带的IOC容器
https://www.itsvse.com/thread-7562-1-1.html
(出处: 架构师_程序员)

ASP.NET Core使用Autofac实现IOC注入
https://www.itsvse.com/thread-7563-1-1.html
(出处: 架构师_程序员)

ASP.NET Core使用Autofac实现AOP拦截
https://www.itsvse.com/thread-7566-1-1.html
(出处: 架构师_程序员)

在新的ASP.NET Core中,大量的采用了依赖注入的方式来编写代码.

比如,在我们的Startup类中的ConfigureServices里,就可以看到:

AddMvc  AddDbContext  包括我们之前目录游览用到的AddDirectoryBrowser..

都是框架提供好的服务,我们直接注入就可以使用了.

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

要使用ioc,需要Startup类引用 Microsoft.Extensions.DependencyInjection(ps,这命名已经很直白了..微软..扩展...依赖注入 - - ,)

  1. public void ConfigureServices(IServiceCollection services)
  2.         {
  3.             services.Configure<CookiePolicyOptions>(options =>
  4.             {
  5.                 // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  6.                 options.CheckConsentNeeded = context => true;
  7.                 options.MinimumSameSitePolicy = SameSiteMode.None;
  8.             });


  9.             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  10.             //添加数据库上下文和配置数据库连接字符串
  11.             PanDb.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
  12.             services.AddDbContext<PanDb>();
  13.             //services.AddDbContext<PanDb>(options =>
  14.             //    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

  15.             services.AddTransient<ITestService1, TestService1>();//瞬时
  16.             services.AddScoped<ITestService2, TestService2>();//作用域
  17.             services.AddSingleton<ITestService3, TestService3>();//唯一 单例
  18.         }
复制代码
注入服务的生命周期

微软给自行注入的服务,提供了3种生命周期.

Transient(瞬时的)

每次请求时都会创建的瞬时生命周期服务。这个生命周期最适合轻量级,无状态的服务。

Scoped(作用域的)

在同作用域,服务每个请求只创建一次。

Singleton(唯一的)

全局只创建一次,第一次被请求的时候被创建,然后就一直使用这一个.

如何使用这三种生命周期呢?.我们直接在注入的时候用不同的方法就行了,代码如下:

  1. services.AddTransient<ITestService1, TestService1>();
  2. services.AddScoped<ITestService2, TestService2>();
  3. services.AddSingleton<ITestService3, TestService3>();
复制代码

下面,我们就来测试一下这三种生命周期的具体生成情况

我们编写三个不同名称的接口并且不同的3个类来实现接口,如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;

  5. namespace BaiDuPan.WebUI
  6. {
  7.     public interface IBaseTestService
  8.     {
  9.         string GetString();
  10.     }

  11.     public interface ITestService1: IBaseTestService { }
  12.     public interface ITestService2 : IBaseTestService { }
  13.     public interface ITestService3 : IBaseTestService { }

  14.     public class TestService1 : ITestService1
  15.     {
  16.         private string str { get; set; }
  17.         public TestService1()
  18.         {
  19.             str = Guid.NewGuid().ToString();
  20.         }
  21.         public string GetString()
  22.         {
  23.             return str;
  24.         }
  25.     }

  26.     public class TestService2 : ITestService2
  27.     {
  28.         private string str { get; set; }
  29.         public TestService2()
  30.         {
  31.             str = Guid.NewGuid().ToString();
  32.         }
  33.         public string GetString()
  34.         {
  35.             return str;
  36.         }
  37.     }

  38.     public class TestService3 : ITestService3
  39.     {
  40.         private string str { get; set; }
  41.         public TestService3()
  42.         {
  43.             str = Guid.NewGuid().ToString();
  44.         }
  45.         public string GetString()
  46.         {
  47.             return str;
  48.         }
  49.     }
  50. }
复制代码
每个实现类的构造函数中,我们都产生了一个新的guid,通过这个GUID,我们可以判断这个类到底重新执行过构造函数没有。

注入服务到控制器

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using Microsoft.AspNetCore.Mvc;
  7. using BaiDuPan.WebUI.Models;

  8. namespace BaiDuPan.WebUI.Controllers
  9. {
  10.     public class HomeController : Controller
  11.     {
  12.         private readonly ITestService1 _testService1;
  13.         private readonly ITestService2 _testService2;
  14.         private readonly ITestService3 _testService3;

  15.         public HomeController(ITestService1 testService1, ITestService2 testService2, ITestService3 testService3)
  16.         {
  17.             _testService1 = testService1;
  18.             _testService2 = testService2;
  19.             _testService3 = testService3;
  20.         }

  21.         //采用了Action注入的方法
  22.         public IActionResult Index([FromServices]ITestService1 testService1_1, [FromServices]ITestService2 testService2_2, [FromServices]ITestService3 testService3_3)
  23.         {
  24.             //瞬时
  25.             ViewBag.Str1 = _testService1.GetString();
  26.             ViewBag.Str1_1 = testService1_1.GetString();

  27.             //作用域
  28.             ViewBag.Str2 = _testService2.GetString();
  29.             ViewBag.Str2_2 = testService2_2.GetString();

  30.             //单例
  31.             ViewBag.Str3 = _testService3.GetString();
  32.             ViewBag.Str3_3 = testService3_3.GetString();
  33.             return View();
  34.         }
  35.     }
  36. }
复制代码
注入的方式一般有三种,构造函数注入, 方法注入,属性注入..微软自带的这个IOC容器,默认采用了构造函数注入的方式(不支持属性注入,不过可以用第三方容器替换来实现)

视图页面代码:

  1. <div class="row">
  2.     <div class="col-md-12">
  3.         <h3>IOC详解,by:https://www.itsvse.com/ </h3>
  4.     </div>
  5.     <div class="col-md-12">
  6.         <p>瞬时:@ViewBag.Str1</p>
  7.         <p>瞬时:@ViewBag.Str1_1</p>
  8.         <p>作用域:@ViewBag.Str2</p>
  9.         <p>作用域:@ViewBag.Str2_2</p>
  10.         <p>单例:@ViewBag.Str3</p>
  11.         <p>单例:@ViewBag.Str3_3</p>
  12.     </div>
  13. </div>
复制代码
运行项目,通过2个不同浏览器进行访问,如下图:



我们发现瞬时生命周期的,2次生成的GUID都不一致,说明对象不是同一个.

然而作用域生命周期的,因为在同一个作用域下,相同浏览器下面2次使用服务的GUID都是一致的,说明用的同一个对象.

单例情况下,两个不同浏览器访问,始终是同一个GUID,说明调用的是同一个对象。

(完)






上一篇:.NET Core Entity使用Entity Framework Core链接数据库
下一篇:ASP.NET Core使用Autofac两种方式实现IOC注入
帖子永久地址: 

架构师_程序员 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与架构师_程序员享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和架构师_程序员的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、架构师_程序员管理员和版主有权不事先通知发贴者而删除本文

码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:help@itsvse.com

QQ|Archiver|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2019-7-18 08:28

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表