ASP.NET Core 3.1 IOC容器以及默认DI以及替换Autofac生命周期
IOC
就是我们需要一个对象 以前我们是去 new 现在我们是直接向 IOC容器 要我们需要的那个对象。
使用一个IOC容器(autofac)通过依赖注入控制各个组件的耦合。也就是说你写好了组件,不需要你去自己控制他们的依赖关系,哪个类又持有哪个类的对象,哪个类里面又要声明一个对象,而是把他们都放到一个容器里面,容器替你做这个(把组件组合起来)。
那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。
DI
由容器动态的将某个依赖关系注入到组件之中 就是 一个对象a 需要去访问数据库 以前我们是自己编写代码去创建一个connction对象 来连接对象,现在我们只需要用@autowrite来获取connection对象,在系统运行时,IOC容器会在合适的时候去创建这个对象,对象a不必关心connection是怎么创建的,何时创建的,这就完成了对各个对象关系的控制
理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
谁依赖于谁:当然是 应用程序依赖于IoC容器
为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源
谁注入谁:很明显是 IoC容器注入应用程序某个对象,应用程序依赖的对象
注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)
Net Core 三个常用的生命周期
首先,我们想象一个这样一个场景。假设我们有寄快递的需求,那么我们会致电快递公司:“我们要寄快递,派一个快递员过来收货”。接着,快递公司会如何做呢?
- 一直派遣同一个快递员来收货。
- 第一周派遣快递员A、第二周派遣快递员B收货。
- 每次都派遣一个新的快递员收货。
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生命周期的更多相关文章
- Asp.Net Core 内置IOC容器的理解
Asp.Net Core 内置IOC容器的理解 01.使用IOC容器的好处 对接口和实现类由原来的零散式管理,到现在的集中式管理. 对类和接口之间的关系,有多种注入模式(构造函数注入.属性注入等). ...
- [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期
生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...
- 简单讲解Asp.Net Core自带IOC容器ServiceCollection
一. 理解ServiceCollection之前先要熟悉几个概念:DIP.IOC.DI.Ioc容器: 二. 接下来先简单说一下几个概念问题: 1.DIP(依赖倒置原则):六大设计原则里面一种设计原 ...
- [IoC容器Unity]第二回:Lifetime Managers生命周期
1.引言 Unity的生命周期是注册的类型对象的生命周期,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,我们也可以显示配置对象的生命周期,Unity将按照配置自动管理,非常方便,下面就介 ...
- [转载][IoC容器Unity]第二回:Lifetime Managers生命周期
1.引言 Unity的生命周期是注册的类型对象的生命周期,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,我们也可以显示配置对象的生命周期,Unity将按照配置自动管理,非常方便,下面就介 ...
- ASP.NET Core中使用IOC三部曲(一.使用ASP.NET Core自带的IOC容器)
前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...
- ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)
前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...
- ASP.NET Core中使用IOC三部曲(三.采用替换后的Autofac来实现AOP拦截)
前言 本文主要是详解一下在ASP.NET Core中,采用替换后的Autofac来实现AOP拦截 觉得有帮助的朋友~可以左上角点个关注,右下角点个推荐 这里就不详细的赘述IOC是什么 以及DI是什么了 ...
- .net core系列之《.net core内置IOC容器ServiceCollection》
一.IOC介绍 IOC:全名(Inversion of Control)-控制反转 IOC意味着我们将对象的创建控制权交给了外部容器,我们不管它是如何创建的,我们只需要知道,当我们想要某个实例时,我们 ...
随机推荐
- SRX_Test_2_sound
声音(sound) [问题描述] 雅礼中学的校门口在修建地铁,而由此带来的噪音问题让周边的居民困扰不已.环保局正在研究 一项评估模型,可以定量评价噪音的危害程度.这项评估模型是这样的:将每一条街道视作 ...
- H3CNE(教程)
培训机构提供的ppt,可能也是来自于官方提供,涉及到H3CNE认证考试中的全部知识点,学真技术还得看这个.包括帧中继,哪怕是淘汰了十多年了. https://huxiaoyao.lanzous.com ...
- 不使用 MQ 如何实现 pub/sub 场景?
hello,大家好,我是小黑,又和大家见面啦~~ 在配置中心中,有一个经典的 pub/sub 场景:某个配置项发生变更之后,需要实时的同步到各个服务端节点,同时推送给客户端集群. 在之前实现的简易版配 ...
- 自动化运维工具之Puppet常用资源(二)
前文我们了解了部分puppet的资源的使用,以及资源和资源的依赖关系的定义,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14071459.html:今天我们继 ...
- java47
1. 1.List集合根据角标获取元素 import java.util.ArrayList; import java.util.List; public class List集合 { @Suppre ...
- oracle ddl 与 dml
DDL create table 创建表 alter table 修改表 drop table 删除表 truncate table 删除表中所有行 create index 创建索引 drop in ...
- 第14.7节 Python模拟浏览器访问实现http报文体压缩传输
一. 引言 在<第14.6节 Python模拟浏览器访问网页的实现代码>介绍了使用urllib包的request模块访问网页的方法.但上节特别说明http报文头Accept-Encodin ...
- 孪生网络入门(下) Siamese Net分类服装MNIST数据集(pytorch)
主题列表:juejin, github, smartblue, cyanosis, channing-cyan, fancy, hydrogen, condensed-night-purple, gr ...
- 一文搞懂RESTful API
RESTful接口实战 原创公众号:bigsai 转载请联系bigsai 文章收藏在回车课堂 前言 在学习RESTful 风格接口之前,即使你不知道它是什么,但你肯定会好奇它能解决什么问题?有什么应用 ...
- 在Centos7下docker配置自动化环境镜像(python3.7+selenium 3.11+firefox 62+geckodriver 0.21)
最近在学习Docker,准备做自动化测试代码集成的功能.如下文章的前提是已经安装好linux系统,且成功安装好Docker. 接下来我会按步骤一步一步的对自动化需要的一些环境进行安装,如果没有特别说明 ...