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意味着我们将对象的创建控制权交给了外部容器,我们不管它是如何创建的,我们只需要知道,当我们想要某个实例时,我们 ...
随机推荐
- yii2.0 ActiveForm 单选框与复选框使用
yii2.0 中的ActiveForm 复选框的使用 默认的复选框选项为纵向的<?= $form->field($model, 'line')->checkboxList(Pictu ...
- Codeforces Round #669 (Div. 2) C. Chocolate Bunny 题解(交互)
题目链接 题目大意 有一个长度为n的全排列,你可以询问2n次,要你经过这个2n次的询问后,求出这个全排列 询问定义为:输入"? i j"输出\(p_{i} mod p_{j}\) ...
- od中低位地址和高位的顺序,以及数据的存放读写
在观察内存的时候应当注意"内存数据"与"数值数据"的区别. 在我们的调试环境中,内存由低到高分布,你可以简单地把这种情形理解成Win32系统在内存中由地位向高位 ...
- 在django中使用原生sql语句
raw # row方法:(掺杂着原生sql和orm来执行的操作) res = CookBook.objects.raw('select id as nid from epos_cookbook whe ...
- linux搭建harbor与使用
条件:安装docker&docker-compose 如未安装,请看:linux离线安装docker + docker-compose harbor 1.下载 下载地址:https://git ...
- 超详细讲解mysql存储过程中的in/out/inout
存储过程 大概定义:用一个别名来描述多个sql语句的执行过程. 最简单 delimiter // create PROCEDURE p1() begin select * from userinfo; ...
- COMMENT SQL二次注入
这题目太顶了进去随便发个贴,出现登录已经提示用户名和密码了,弱密码登录(得自己去爆破)zhangwei666即可 没啥思路,扫下目录试试,kali的dirb扫到.git泄露githacker得到源码看 ...
- [MRCTF2020]Ezpop
题目: Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki ...
- 西湖论剑2020MISC-Yusa_yyds
非常规USB流量分析 附件下载: 链接:https://pan.baidu.com/s/1Gjgj1EH9qmX0PYi21uYlDg 提取码:x9xn 先提取USB流量数据,使用工具: https: ...
- BUUOJ 杂项MISC(1)
爱因斯坦 下载之后解压打开是一张爱因斯坦的图片,看来是图片隐写题 使用binwalk -e misc2.jpg 获得一个有flag.txt的压缩包,但是需要密码才能打开,猜想密码在图片里面,把图片丢进 ...