IOC

就是我们需要一个对象 以前我们是去 new 现在我们是直接向 IOC容器 要我们需要的那个对象。

使用一个IOC容器(autofac)通过依赖注入控制各个组件的耦合。也就是说你写好了组件,不需要你去自己控制他们的依赖关系,哪个类又持有哪个类的对象,哪个类里面又要声明一个对象,而是把他们都放到一个容器里面,容器替你做这个(把组件组合起来)。

那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。

DI

由容器动态的将某个依赖关系注入到组件之中 就是 一个对象a 需要去访问数据库 以前我们是自己编写代码去创建一个connction对象 来连接对象,现在我们只需要用@autowrite来获取connection对象,在系统运行时,IOC容器会在合适的时候去创建这个对象,对象a不必关心connection是怎么创建的,何时创建的,这就完成了对各个对象关系的控制

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

谁依赖于谁:当然是 应用程序依赖于IoC容器

为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源

谁注入谁:很明显是 IoC容器注入应用程序某个对象,应用程序依赖的对象

注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

Net Core 三个常用的生命周期

首先,我们想象一个这样一个场景。假设我们有寄快递的需求,那么我们会致电快递公司:“我们要寄快递,派一个快递员过来收货”。接着,快递公司会如何做呢?

  1. 一直派遣同一个快递员来收货。
  2. 第一周派遣快递员A、第二周派遣快递员B收货。
  3. 每次都派遣一个新的快递员收货。

1.Transient(瞬态模式):每一次GetService都会创建一个新的实例   瞬间生命周期 : 每次需要创建一个全新的 每次请求时都会创建的瞬时生命周期服务。这个生命周期最适合轻量级,无状态的服

2.Scoped(作用域模式):在同一个Scope内只初始化一个实例 ,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内) 单例进程唯一实例 :每一次请求都是同一个(多用于时间) 在同作用域,服务每个请求只创建一次。

3.Singleton(单例模式):整个应用程序生命周期内只创建一个实例   全局只创建一次,第一次被请求的时候被创建,然后就一直使用这一个.

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

//注册不同生命周期的服务
services.AddTransient<ITestService, TestService>();
services.AddScoped<ITestService2, TestService2>();
services.AddSingleton<ITestService3, TestService3>();  

自带的IOC 做一些小的项目完全没有问题,但是大项目使用起来就比较单一

IOC容器替换为Autofac

AutoFac生命周期

InstancePerLifetimeScope:作用域模式  在一个嵌套语句块中,只会返回一个实例。 在解决每个生命周期实例作用域组件时,每个嵌套作用域将获得一个实例(例如,每个工作单元)。相当于AddScope

SingleInstance:单例模式,每次调用,都会使用同一个实例化的对象;每次都用同一个对象;相当于AddSingleton

InstancePerDependency:瞬态模式  默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象;AddTransient

Autofac可完美替换系统的依赖注入功能,可实现构造函数注入和属性注入,替换过程:

在Program.cs 新增一行代码

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())//集成Autofac
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});

然后在Startup.cs 增加方法

         //集成Autofac
public void ConfigureContainer(ContainerBuilder builder)
{
//添加依赖注入实例,AutofacModuleRegister就继承自Autofac.Module的类
builder.RegisterModule(new StartupHelp.AutofacModuleRegister());
}

ConfigureAutofac 是自己封装的一个类  继承了 Autofac.Module

其中注册类必须继承自Autofac.Module,并且在Load中实现注入,此处应用了程序集范围的注入以及单个对象的注入,最后添加的代码是为了支持控制器的属性注入。

注入的接口(如IUnitOfWork)和实现(UnitOfWork)没有特别。

注入对象的生命周期与.netcore内置的一致

public class AutofacRegister : Autofac.Module
{
#region 单个类和接口
//直接注册某一个类和接口
//左边的是实现类,右边的As是接口
//containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>().SingleInstance();
//这里就跟默认DI差不多
//services.AddScoped<TestServiceE, ITestServiceE>();
#endregion #region 方法1 Load 适用于无接口注入
//var assemblysServices = Assembly.Load("Exercise.Services"); //containerBuilder.RegisterAssemblyTypes(assemblysServices)
// .AsImplementedInterfaces()
// .InstancePerLifetimeScope(); //var assemblysRepository = Assembly.Load("Exercise.Repository"); //containerBuilder.RegisterAssemblyTypes(assemblysRepository)
// .AsImplementedInterfaces()
// .InstancePerLifetimeScope(); #endregion #region 方法2 选择性注入 与方法1 一样
// Assembly Repository = Assembly.Load("Exercise.Repository");
// Assembly IRepository = Assembly.Load("Exercise.IRepository");
// containerBuilder.RegisterAssemblyTypes(Repository, IRepository)
//.Where(t => t.Name.EndsWith("Repository"))
//.AsImplementedInterfaces().PropertiesAutowired(); // Assembly service = Assembly.Load("Exercise.Services");
// Assembly Iservice = Assembly.Load("Exercise.IServices");
// containerBuilder.RegisterAssemblyTypes(service, Iservice)
//.Where(t => t.Name.EndsWith("Service"))
//.AsImplementedInterfaces().PropertiesAutowired();
#endregion #region 方法3 使用 LoadFile 加载服务层的程序集 将程序集生成到bin目录 实现解耦 不需要引用
//获取项目路径
//var basePath = Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
//var ServicesDllFile = Path.Combine(basePath, "Exercise.Services.dll");//获取注入项目绝对路径
//var assemblysServices = Assembly.LoadFile(ServicesDllFile);//直接采用加载文件的方法
//containerBuilder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces(); //var RepositoryDllFile = Path.Combine(basePath, "Exercise.Repository.dll");
//var RepositoryServices = Assembly.LoadFile(RepositoryDllFile);//直接采用加载文件的方法
//containerBuilder.RegisterAssemblyTypes(RepositoryServices).AsImplementedInterfaces();
#endregion #region 在控制器中使用属性依赖注入,其中注入属性必须标注为public
//public ITestServiceE _testService {get;set }
//注意 上方为属性注入 发现为Null 需要在Startup.cs 的 ConfigureServices 方法下加入如下代码
//services.AddControllers().AddControllersAsServices(); //在控制器中使用属性依赖注入,其中注入属性必须标注为public
// var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
//.Where(type => typeof(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray();
// containerBuilder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
#endregion /// <summary>
/// 当前使用
/// </summary>
/// <param name="builder"></param>
protected override void Load(ContainerBuilder builder)
{
//程序集范围注入 将匹配所有Service结尾的
builder.RegisterAssemblyTypes(typeof(SysUserService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces().PropertiesAutowired();
//单个注册 工作单元 和数据库上下文
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().PropertiesAutowired();
builder.RegisterType<dbContext>().As<DbContext>().PropertiesAutowired(); //在控制器中使用属性依赖注入,其中注入属性必须标注为public 就是不需要通过构造函数 直接
//public ITestServiceE _testService {get;set } 可直接_testService.方法 不许在构造函数接收
//注意属性注入 发现为Null 需要在Startup.cs 的 ConfigureServices 方法下加入如下代码
//services.AddControllers().AddControllersAsServices();
var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
.Where(type => typeof(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray();
builder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
}
}

然后控制器通过构造函数注入,或者属性注入测试

ASP.NET Core 3.1 IOC容器以及默认DI以及替换Autofac生命周期的更多相关文章

  1. Asp.Net Core 内置IOC容器的理解

    Asp.Net Core 内置IOC容器的理解 01.使用IOC容器的好处 对接口和实现类由原来的零散式管理,到现在的集中式管理. 对类和接口之间的关系,有多种注入模式(构造函数注入.属性注入等). ...

  2. [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期

    生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...

  3. 简单讲解Asp.Net Core自带IOC容器ServiceCollection

    一.  理解ServiceCollection之前先要熟悉几个概念:DIP.IOC.DI.Ioc容器: 二.  接下来先简单说一下几个概念问题: 1.DIP(依赖倒置原则):六大设计原则里面一种设计原 ...

  4. [IoC容器Unity]第二回:Lifetime Managers生命周期

    1.引言 Unity的生命周期是注册的类型对象的生命周期,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,我们也可以显示配置对象的生命周期,Unity将按照配置自动管理,非常方便,下面就介 ...

  5. [转载][IoC容器Unity]第二回:Lifetime Managers生命周期

    1.引言 Unity的生命周期是注册的类型对象的生命周期,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,我们也可以显示配置对象的生命周期,Unity将按照配置自动管理,非常方便,下面就介 ...

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

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

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

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

  8. ASP.NET Core中使用IOC三部曲(三.采用替换后的Autofac来实现AOP拦截)

    前言 本文主要是详解一下在ASP.NET Core中,采用替换后的Autofac来实现AOP拦截 觉得有帮助的朋友~可以左上角点个关注,右下角点个推荐 这里就不详细的赘述IOC是什么 以及DI是什么了 ...

  9. .net core系列之《.net core内置IOC容器ServiceCollection》

    一.IOC介绍 IOC:全名(Inversion of Control)-控制反转 IOC意味着我们将对象的创建控制权交给了外部容器,我们不管它是如何创建的,我们只需要知道,当我们想要某个实例时,我们 ...

随机推荐

  1. 写给程序员的机器学习入门 (九) - 对象识别 RCNN 与 Fast-RCNN

    因为这几个月饭店生意恢复,加上研究 Faster-RCNN 用掉了很多时间,就没有更新博客了.这篇开始会介绍对象识别的模型与实现方法,首先会介绍最简单的 RCNN 与 Fast-RCNN 模型,下一篇 ...

  2. Educational Codeforces Round 96 (Rated for Div. 2) E. String Reversal 题解(思维+逆序对)

    题目链接 题目大意 给你一个长度为n的字符串,可以交换相邻两个元素,使得这个字符串翻转,求最少多少种次数改变 题目思路 如果要求数组排序所需要的冒泡次数,那其实就是逆序对 这个也差不多,但是如果是相同 ...

  3. 败家玩意儿!Redis 竟然浪费了这么多内存!

    作为内存数据库,内存空间大小对于 Redis 来说是至关重要的.内存越多,意味着存储的数据也会越多.但是不知道你有没有遇到过这样的情况,明明空间很大,但是内存的使用却不是很理想. 为什么会出现这样的情 ...

  4. iptables SNAT 和DNAT的转化配置实验

    原文链接:http://www.jb51.net/LINUXjishu/402441.html DNAT(Destination Network Address Translation,目的地址转换) ...

  5. 【NOIP2011模拟11.1】钓鱼

    钓鱼 题目 Description 我们把钓鱼的过程放在坐标系里来考虑.图中蓝色的点为船,初始时它的坐标记为(Ax,y).河深为y,河宽为x.某个时刻会从左边界或右边界游出来一条鱼(左边的往右边游,右 ...

  6. 20200513_安装windows sql server 2012 _ ws功能 NetFx3时出错,错误代码:-2146498298

    这是没有安装.net Framework 3.5造成的 1. 下载个.net Framework 3.5, 放到任意目录下, 比如C: 2. 打开添加windows 功能 3. 直接下一步: 4. 勾 ...

  7. Zabbix监控使用进阶

    1. Zabbix基于SNMP监控 1.1 zabbix-web所能指定的监控方式 ssh/telnet agent:master/agent SNMP:Simple Network Manageme ...

  8. 第14.7节 Python模拟浏览器访问实现http报文体压缩传输

    一. 引言 在<第14.6节 Python模拟浏览器访问网页的实现代码>介绍了使用urllib包的request模块访问网页的方法.但上节特别说明http报文头Accept-Encodin ...

  9. vue中两行代码实现全选及子选项全部选中,则全选按钮选中,反之有一个没选中,就取消选中全选按钮

    every() 方法使用指定函数检测数组中的所有元素: 如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测. 如果所有元素都满足条件,则返回 true. 逻辑 ...

  10. W12Scan和taoman批量刷edusrc(单机)

    昨天看到教育漏洞群里面发了利用w12scan和taoman两个开源工具批量刷edusrc的帖子链接, https://www.bugku.com/thread-3810-1-1.html 跟着帖子上面 ...