ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器)

前言

本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期.这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度.

正文

今天我们主要讲讲如何使用自带IOC容器,emm..虽然自带的功能不是那么强大,但是胜在轻量级..而且..不用引用别的库..

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

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

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

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

 

1.如何注入自己的服务

下面我们就来讲讲如何注入自己的服务.

首先,我们编写我们自己的测试服务如下:

public class TestService: ITestService

    {

        public TestService()

        {

            MyProperty = Guid.NewGuid();

        }

        public Guid MyProperty { get; set; }

        public List<string> GetList(string a)

        {

            return new List<string>() { "LiLei", "ZhangSan", "LiSi" };

        }

    }

编写对应的接口代码如下:

    public interface ITestService{Guid MyProperty { get; }List<string> GetList(string a);}

 

然后,我们要在Startup类引用 Microsoft.Extensions.DependencyInjection(ps,这命名已经很直白了..微软..扩展...依赖注入 - - ,)

修改ConfigureServices方法,如下:

       public void ConfigureServices(IServiceCollection services)

        {

            services.AddMvc();

            services.AddDbContext<BloggingContext>();

             //这里就是注入服务

            services.AddTransient<ITestService, TestService>();

            services.AddDirectoryBrowser();

        }

AddTransient就是注入的方法之一,泛型参数,前面一个是你服务的接口,第二个是服务的实现类..

这样,我们就完成了初步的注入操作.

那么我们如何使用我们注入的服务呢?

我们到控制器,编写代码如下:

public class DITestController : Controller

    {

            private readonly ITestService _testService;

            public DITestController(ITestService testService)

            {

                   _testService = testService;

             }

             public IActionResult Index()

            {

                ViewBag.date = _testService.GetList("");

                return View();

             }

    }

注入的方式一般有三种,构造函数注入, 方法注入,属性注入..微软自带的这个IOC容器,默认采用了构造函数注入的方式(不支持属性注入,不过可以用第三方容器替换来实现,下篇讲)

我们编写我们的index视图如下:

@{ViewData["Title"] = "Index";
}<h2>Index</h2>@foreach (var item in ViewBag.date)
{    <h2>@item</h2>}

最终效果如下:

2.注入服务的生命周期

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

Transient(瞬时的)

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

Scoped(作用域的)

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

Singleton(唯一的)

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

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

 services.AddTransient<ITestService, TestService>();services.AddScoped<ITestService2, TestService2>();services.AddSingleton<ITestService3, TestService3>();

 

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

我们编写三个不同名称的接口如下:

public interface ITestService

    {

        Guid MyProperty { get; }

        List<string> GetList(string a);

    }

    public interface ITestService2

    {

        Guid MyProperty { get; }

        List<string> GetList();

    }

    public interface ITestService3

    {

        Guid MyProperty { get; }

        List<string> GetList();

    }

然后用3个类来分别实现他们.

public class TestService: ITestService

    {

        public TestService()

        {

            MyProperty = Guid.NewGuid();

        }

        public Guid MyProperty { get; set; }

        public List<string> GetList(string a)

        {

            return new List<string>() { "LiLei", "ZhangSan", "LiSi" };

        }

    }


    public class TestService2 : ITestService2

    {

        public TestService2()

        {

            MyProperty = Guid.NewGuid();

        }

        public Guid MyProperty { get; set; }

        public List<string> GetList()

        {

            return new List<string>() { "LiLei", "ZhangSan", "LiSi" };

        }

    }

    public class TestService3 : ITestService3

    {


        public TestService3()

        {

            MyProperty = Guid.NewGuid();

        }

        public Guid MyProperty { get; set; }

        public List<string> GetList()

        {

            return new List<string>() { "LiLei", "ZhangSan", "LiSi" };

        }

    }

每个实现类的构造函数中,我们都产生了一个新的guid,通过这个GUID,我们可以判断这个类到底重新执行过构造函数没有.

我们编写注入代码如下:

public void ConfigureServices(IServiceCollection services)

        {

            services.AddMvc();

            services.AddDbContext<BloggingContext>();

            services.AddTransient<ITestService, TestService>();

            services.AddScoped<ITestService2, TestService2>();

            services.AddSingleton<ITestService3, TestService3>();

            services.AddDirectoryBrowser();

        }

我们修改控制器如下:

public class DITestController : Controller

    {


        private readonly ITestService _testService;

        private readonly ITestService2 _testService2;

        private readonly ITestService3 _testService3;

        public DITestController(ITestService testService, ITestService2 testService2, ITestService3 testService3)

        {

            _testService = testService;

            _testService2 = testService2;

            _testService3 = testService3;

        }

        //这里采用了Action注入的方法

        public IActionResult Index([FromServices]ITestService testService11, [FromServices]ITestService2 testService22)

        {

            ViewBag.date = _testService.GetList("");

            ViewBag.guid = _testService.MyProperty;

            ViewBag.guid11 = testService11.MyProperty;

            ViewBag.guid2 = _testService2.MyProperty;

            ViewBag.guid22 = testService22.MyProperty;

            ViewBag.guid3 = _testService3.MyProperty;

            return View();

        }

}

这里说明一下,我们采用了Action注入的方法,新注入了一个ITestService2 ,来保证2个ITestService2 在同一个作用域. 

我们编写相关的index页面,来展示这些信息如下:

@{

    ViewData["Title"] = "Index";

}


<h2>Index</h2>

@foreach (var item in ViewBag.date)

{


    <h2>@item</h2>

}


<h1>瞬时的:@ViewBag.guid</h1>

<h1>瞬时的2:@ViewBag.guid11</h1>

<h1>作用域的:@ViewBag.guid2</h1>

<h1>作用域的2:@ViewBag.guid22</h1>

<h1>全局唯一的:@ViewBag.guid3</h1>


我们运行代码,第一次访问,效果如下:

 

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

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

我们直接刷新页面进行第二次访问.

效果如下:

瞬时的和作用域的,都继续符合我们的预期,

全局唯一生命周期的和上面第一次访问的GUID保持一致.说明2次访问,都使用的同一个对象.也符合我们的预期. 

写在最后

本篇到此就结束了,下篇我们讲解,如何使用第三方的Autofac来替换我们默认的IOC容器,并且使用Autofac的属性注入,来注入我们的服务.  喜欢的请点个推荐和关注,~有问题也希望各位批评指正~.

原文地址:http://www.cnblogs.com/GuZhenYin/p/8297145.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P4130,jzoj1214-[NOI2007]项链工厂【线段树】

正题 题目链接:https://www.luogu.org/problemnew/show/P4130 题目大意 一个环形颜色珠子链&#xff0c;位置(注意不是上面的珠子)从最上顺时针下来位置依次标号1∼n1\sim n1∼n。 然后要求支持以下操作 Rk:R\ k:R k:将所有珠子顺时针旋转kkk个。F:F:F:将所有珠子以111向下翻…

LeetCode常用算法模式大厂面试题整理

转载自 LeetCode常用算法模式&大厂面试题整理 文章目录 1、滑动窗口 2、双指针 3、快慢指针 4、合并区间 5、循环排序 6、就地反转链表 7、堆-优先队列问题 8、Top K 9、归并 10、单调栈 11、回溯法 BATJ等大厂面试真题汇总 1、滑动窗口 1 一个左指针&#xff0c;一个右…

ABPZero系列教程之拼多多卖家工具

此系列文章围绕着拼多多卖家工具来介绍ABPZero的使用&#xff0c;内容包括手机登录、手机注册、拼团提醒、微信公众号绑定帐号、有拼团发送消息到微信公众号&#xff08;只要关注过微信公众号并已绑定系统帐号&#xff09;。学习此系列必备&#xff1a;手机验证码&#xff1a;使…

欢乐纪中某A组赛【2019.7.6】

前言 斐大爷NBNBNB 成绩 JJJ表示初中&#xff0c;HHH表示高中后面加的是几年级 RankRankRankPersonPersonPersonScoreScoreScoreAAABBBCCC555(J−2)WYC(J-2)WYC(J−2)WYC210210210100100100100100100101010666(J−3)ZZY(J-3)ZZY(J−3)ZZY200200200100100100100100100000666(J−…

详解Vue中watch的高级用法

转载自 详解Vue中watch的高级用法 我们通过实例代码给大家分享了Vue中watch的高级用法&#xff0c;对此知识点有需要的朋友可以跟着学习下。 假设有如下代码&#xff1a; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <div> <p>FullName: {{fullName}}<…

g4e基础篇#4 了解Git存储库(Repo)

Git 存储库看上去就是一个文件夹&#xff0c;只是在这个文件夹中不仅仅保存了所有文件的当前版本&#xff0c;也同时保存了所有的历史记录&#xff0c;这些额外的信息都保存在当前文件夹下面的.git子目录中。因为前面我们所描述的git跟踪改动的特殊方式 &#xff0c;git可以在很…

P3846-[TJOI2007]可爱的质数【BSGS,数论】

正题 题目链接:https://www.luogu.org/problemnew/show/P3846 题目大意 BL≡N(modP)B^L\equiv N(mod\ P)BL≡N(mod P) 求最小的LLL。 解题思路 首先为了顺眼改一下变量名 Ax≡B(modP)A^x\equiv B(mod\ P)Ax≡B(mod P) 然后我们设xi∗t−j(0≤i≤t,0≤j≤t−1)xi*t-j(0\leq i\…

Oracle常用查询语句

Oracle常用查询语句 查看当前用户的缺省表空间SQL>select username,default_tablespace from user_users;查看当前用户的角色SQL>select * from user_role_privs;查看当前用户的系统权限和表级权限SQL>select * from user_sys_privs;SQL>select * from user_tab_p…

net的retrofit--WebApiClient库

# 库简介WebApiClient是开源在github上的一个httpClient客户端库&#xff0c;内部基于HttpClient开发&#xff0c;是一个只需要定义c#接口(interface)&#xff0c;并打上相关特性&#xff0c;即可异步调用http-api的框架 &#xff0c;支持.net framework4.5、netcoreapp2.0和ne…

P5021-赛道修建【平衡树,贪心,二分答案】

正题 题目链接:https://www.luogu.org/problemnew/show/P5021 题目大意 一棵树找mmm条不重边路径使得最短的那条最长。 解题思路 首先最小的最大显然二分一下答案。之后问题转换为找最多条长度不小于midmidmid的路径。 如果dpdpdp的话需要二维&#xff0c;显然不能胜任本题…

Sentinel(一)之简介

转载自 Sentinel: 分布式系统的流量防卫兵 Sentinel 是什么&#xff1f; 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从限流、流量整形、熔断降级、系统负…

使用xUnit为.net core程序进行单元测试(中)

第一部分: 使用xUnit为.net core程序进行单元测试(上), 下面有一点点内容是重叠的....String Assert测试string是否相等&#xff1a;[Fact]public void CalculateFullName(){var p new Patient{FirstName "Nick",LastName "Carter"};Assert.Equal(&quo…

P2048-[NOI2010]超级钢琴【RMQ,堆】

正题 题目链接:https://www.luogu.org/problemnew/show/P2048 题目大意 一个长度为nnn序列aaa。寻找kkk个子序列要求长度在L∼RL\sim RL∼R之间&#xff0c;求这kkk个子序列的最大和。 解题思路 首先对aaa求出前缀和数组sss。题目转换为求kkk个数对要求两两之间距离在L∼RL\…

Sentinel(二)之Quick Start

转载自 Sentinel Quick Start 1.1 公网 Demo 如果希望最快的了解 Sentinel 在做什么&#xff0c;我们可以通过 Sentinel 新手指南 来运行一个例子&#xff0c;并且能在云上控制台上看到最直观的监控和流控效果等。 1.2 手动接入 Sentinel 以及控制台 下面的例子将展示应用如…

hdu5115-Dire Wolf【区间dp】

正题 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid5115 题目大意 有nnn只狼&#xff0c;击败第iii只狼会扣aia_iai​加上于其相邻的狼的blbrb_lb_rbl​br​点hphphp。注意该狼被击败后会使原来于其相邻的狼变的相邻。 解题思路 显然区间dpdpdp&#xff0c;设fi,jf_…

.net的retrofit--WebApiClient库深入篇

前言本篇文章的内容是对上一篇.net的retrofit--WebApiClient库的深层次补充&#xff0c;你可能需要先阅读上一篇才能理解此篇文章。本文将详细地讲解WebApiClient的原理&#xff0c;结合实际项目中可能遇到的问题进行使用说明。库简介WebApiClient是开源在github上的一个httpCl…

Sentinel(三)之如何使用

转载自 Sentinel如何使用 简介 Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard。核心库不依赖 Dashboard&#xff0c;但是结合 Dashboard 可以取得最好的效果。 这篇文章主要介绍 Sentinel 核心库的使用。如果希望有一个最快最直接的了解&#xff0c;可以参考 新手指…

jzoj4485-[GDOI 2016 Day1]第一题 中学生数学题【数学】

正题 题目大意 给出n0,k,p0n_0,k,p_0n0​,k,p0​ 然后有两问&#xff0c;求 ⌊n0−kp⌋(p−p0)\lfloor n_0-kp\rfloor (p-p_0)⌊n0​−kp⌋(p−p0​)的最大值&#xff0c;ppp为任意实数。⌊n0−kp1⌋(p1−p0)(⌊n0−kp2⌋−n1)(p2−p0)\lfloor n_0-kp_1\rfloor (p_1-p_0)(\lf…

ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)

上一篇ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器) ,我们说过ASP.NET Core中自带的IOC容器是属于轻量级的,功能并不是很多,只是提供了基础功能而已..所以今天我们主要讲讲如何采用Autofac来替换IOC容器,并实现属性注入注意:本文需要读者理解DI IOC并使用过…