.Net Core依赖注入

news2024/12/28 20:46:39

.Net Core依赖注入

往期文章:

  1. .ner Core实现接口限流
  2. .net Core程序发布到IIS(Window Server 2019)

文章目录

  • .Net Core依赖注入
  • 前言
  • 一、ICO 和DI和DL
    • ICO [控制反转]
    • DI [依赖注入]
    • DL [依赖查找]
  • 二、.net Core 中的依赖注入【Autofac】
    • 瞬时模式
    • 作用域模式
    • 单例模式
    • 尝试注册
    • 移除和替换注册
    • 注册泛型模板
  • 三、使用依赖注入注意点:
  • 四、实现 IDisposable 接口类型的释放
  • 五、Autofac与.netCore自带的依赖注入对比
    • 基于名称的注入
    • 属性注入
    • 子容器
    • 基于动态代理的 AOP
  • 六、.netCore 6.0 中依赖注入的使用


前言

相信大家在学习.net Core的时候都听说过依赖注入,和控制反转等概念。随着.net Core 6.0的到来,相比于之前的.net Core 3.1 做了不小的改变,依赖注入的方式也和之前的方式有些许不同,但是万变不离其宗,如果你会用.net Core 3.1那.net Core 6.0应该也能很快上手,不会.net Core 3.1的同学也不用担心,相信你看了下面的教程也能学会如果依赖注入。


一、ICO 和DI和DL

学习.net Core 的同学都应该听说过这两个东西。那么他们分别是什么呢?他们呢各自的作用又是什么呢?接下来我就来给大家讲解一下。

ICO [控制反转]

ICO:它的全称是【Inversion of Control】翻译过来就是控制反转。

大佬是这样说的:

所谓控制反转,反转的是类与类之间依赖的创建。类型A依赖于类型B时,不依赖于具体的类型,而是依赖于抽象,不在类A中直接 new 类B的对象,而是通过外部传入依赖的类型对象,以实现类与类之间的解耦

好像不太好理解,给大家举个例子:

比如你去你妹妹家串门,而她做的饭巨难吃,你就自己带着一同泡面去串门,吃饭的时候就吃自己带的这桶泡面。此时你就实现了控制反转,不用吃你妹妹做的黑暗料理了。

DI [依赖注入]

DI:它的全称是【Dependency Injection】翻译过来就是依赖注入。
大佬的解释是:

所谓依赖注入,就是由一个外部容器对各种依赖类型对象进行管理,包括对象的创建、销毁、状态保持等,并在某一个类型需要使用其他类型对象的时候,由容器进行传入。

好像还是不太好理解,再给大家举个例子:

比如你要出去旅行,把牙刷,毛巾,出行所需的衣物和鞋子等东西装入背包,这些物品都是你此次旅行可能需要的东西也就是依赖。你把它装入背包的过程就可以理解为依赖注入。

DL [依赖查找]

DL:它的全称是【Dependency Lookup】翻译过来是依赖查找。
大佬是这样描述它的:

它是控制反转设计原则的一种实现方式。它的大体思路是:容器中的受控对象通过容器的 API 来查找自己所依赖的资源和协作对象。这种方式虽然降低了对象间的依赖,但是同时也使用到了容器的 API,造成了我们无法在容器外使用和测试对象。依赖查找是一种更加传统的 IOC 实现方式。
依赖查找也有两种方式:

  1. 依赖拖拽:注入的对象如何与组件发生联系,这个过程就是通过依赖拖拽实现;
  2. 上下文依赖查找:在某些方面跟依赖拖拽类似,但是上下文依赖查找中,查找的过程是在容器管理的资源中进行的,而不是从集中注册表中,并且通常是作用在某些设置点上;(JNDI)

这个就很好理解了就不用给大家举例子了。

二、.net Core 中的依赖注入【Autofac】

Autofac 中依赖的三种生命周期:

瞬时模式

  • Transient:瞬时模式,每次请求,都获取一个新的实例。即使同一个请求获取多次也会是不同的实例,它会在这个请求处理结束后被释放

示例:

 services.AddTransient<IWebService, WebService>();

作用域模式

  • Scoped:作用域模式,每个客户端请求(连接)创建一次。同一个请求获取多次会得到相同的实例,它也会在这个请求处理结束后被释放

示例:

 services.AddScoped<IWebService, WebService>();

单例模式

  • Singleton:单例模式,每次都获取同一个实例,它会在根容器释放的时候释放

示例:

 services.AddSingleton<IWebService, WebService>();

权重大小对比:Singleton>Transient>Scoped

注入形式展示:

  1. 直接注入实例
 services.AddScoped<IMyService>(new MyService());

  1. 工厂模式注册
 services.AddScoped<IMyService>(serviceProvider =>
 {
    return new MyService();
 });
  1. 注册不同示例
 services.AddScoped<IMyService>(new MyService());
 services.AddScoped<IMyService>(new MyService2());

尝试注册

尝试注册会先判断实例是否已经注册,若注册了则不再进行注册;尝试注册可以有效的避免服务重复注册。

 services.TryAddScoped<IMyService>(new MyService());
 services.TryAddEnumerable(ServiceDescriptor.Scoped<IMyService, MyService>());

移除和替换注册

替换注册可以替换原有实例注册MyService为MyService2,RemoveAll则是移除所以实现了IMyService的注册实例。

 services.AddScoped<IMyService, MyService>();
 services.Replace(ServiceDescriptor.Singleton<IMyService, MyService2>());
 services.RemoveAll<IMyService>();

注册泛型模板

 services.AddScoped(typeof(IGenericService<>), typeof(GenericService<>));

三、使用依赖注入注意点:

  • 避免通过静态属性的方式访问容器对象
  • 避免在服务内部使用 GetService 方式来获取实例
  • 避免使用静态属性存储单例,应该使用容器管理单例对象
  • 避免在服务中实例化依赖对象,应该使用依赖注入来获得依赖对象
  • 避免向单例的类型注入范围的类型

四、实现 IDisposable 接口类型的释放

  • DI 只负责释放由其创建的对象实例
  • DI 在容器或子容器释放时,释放由其创建的对象实例
  • 避免手动创建实现了 IDisposable 对象,应该使用容器来管理其生命周期

五、Autofac与.netCore自带的依赖注入对比

Autofac的功能比.Net Core 的原生依赖注入更丰富,具体表现在:

  • 基于名称的注入
  • 属性注入
  • 子容器
  • 基于动态代理的 AOP

基于名称的注入

public void ConfigureContainer(ContainerBuilder builder)
{
    builder.RegisterType<MyService>().Named<IMyService>("s1");
    builder.RegisterType<MyService2>().Named<IMyService>("s1");
}

从IoC容器中使用ResolveNamed获取:

var s1 = container.ResolveNamed<IMyService>("s1");
var s2 = container.ResolveNamed<IMyService>("s2");

属性注入

用PropertiesAutowired方法支持属性注入:

builder.RegisterType<MyService>().As<IMyService>().PropertiesAutowired();

子容器

builder.RegisterType<MyService>().InstancePerMatchingLifetimeScope("myscope");

子容器的使用:

var autofacContainer = app.ApplicationServices.GetAutofacRoot();
using (var myscope = autofacContainer.BeginLifetimeScope("myscope"))
{
    var service1 = myscope.Resolve<MyService>();
    using (var scope = myscope.BeginLifetimeScope())
    {
        var service2 = scope.Resolve<MyService>();
        Console.WriteLine($"service1=service2:{service1 == service2}");
    }
}

基于动态代理的 AOP

需要引用包:Autofac.Extras.DynamicProxy
先实现一个拦截器继承 IInterceptor

    public class MyInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            Console.WriteLine($"Intercept before,Method:{invocation.Method.Name}");
            invocation.Proceed();
            Console.WriteLine($"Intercept after,Method:{invocation.Method.Name}");
        }
    }

注册

builder.RegisterType<MyService>().As<IMyService>().PropertiesAutowired().InterceptedBy(typeof(MyInterceptor)).EnableInterfaceInterceptors();

这里实现了基于接口的拦截,也可以实现基于类的拦截;基于类的拦截时,方法需要定义为虚方法。

示例代码搬运自:Aoss丶的博客->.Net Core 依赖注入

六、.netCore 6.0 中依赖注入的使用

  1. 第一步、添加依赖注入的两个关键包:
    Autofac.Extensions.DependencyInjection 和 Autofac.Extras.DynamicProxy
    在这里插入图片描述

  2. 第二步、重写load方法:
    这种方法式为了配合程序集注入的
    这里注意:根据名称约定 查询到的程序集 的命名规则必须规范 否则可能读取不到 对应的数据集 从而报错在这里插入图片描述

  3. 第三步,在Program.cs中注册:

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
    //第一种方式 实现和接口方式注入
    builder.RegisterType<LoginServices>().As<ILoginServices>();
    //第二中调用程序集注入(引用式)
    builder.RegisterModule(new AutofacModuleRegister());

    //第二种注入方式  程序集注入(反射式)
    var assemblysServices = Assembly.Load("AutofacModuleRegister");
    builder.RegisterAssemblyTypes(assemblysServices)
               .AsImplementedInterfaces()
               .InstancePerLifetimeScope();

});
  1. 第四步,在构造函数中注入:
    在这里插入图片描述

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

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

相关文章

Android Dalvik 虚拟机(详细版)

经典好文推荐,通过阅读本文,您将收获以下知识点: 1.Java 语言在Android 上运行流程 2.虚拟机发展过程 3.Android Dalvik 模式 4.Android N 中dex2oat 原理以及模式 5.如何判断dex2oat 采用的相关参数 6.如何查看dex2oat 的log 7.什么时候进行dex2oat 8.手机反应慢的原因 9.解…

再获权威认可!MIAOYUN荣获中国信通院一云多芯优秀案例,荣登《云管理产品与服务图谱》

2023年7月25日&#xff0c;以“云领创新&#xff0c;算启新篇”为主题的2023可信云大会在北京国际会议中心顺利召开。会上中国信息通信研究院发布了一云多芯稳定安全运行优秀案例和业界首个《云管理产品与服务图谱&#xff08;2023&#xff09;》。成都元来云志科技有限公司&am…

QEMU源码全解析12 —— QOM介绍(1)

接前一篇文章&#xff1a;QEMU源码全解析11 —— 定义一个QEMU模块&#xff08;3&#xff09; 本文内容参考&#xff1a; 《趣谈Linux操作系统》 —— 刘超&#xff0c;极客时间 《QEMU/KVM》源码解析与应用 —— 李强&#xff0c;机械工业出版社 特此致谢&#xff01; 前几…

springboot创建并配置环境(一) - 创建环境

文章目录 一、介绍二、启动环境Environment的分析三、进入源码四、创建环境1. 如何确定应用类型2. 测试 一、介绍 在springboot的启动流程中&#xff0c;启动环境Environment是可以说是除了应用上下文ApplicationContext之外最重要的一个组件了&#xff0c;而且启动环境为应用…

5点搞透电阻选型

一提到电阻&#xff0c;大家肯定会想到一个人&#xff1a;欧姆。 欧姆(Georg Simon 0hm&#xff0c;1787~1854年)是德国物理学家。生于巴伐利亚埃尔兰根城。欧姆定律及其公式的发现&#xff0c;给电学的计算&#xff0c;带来了很大的方便。 人们为了纪念他&#xff0c;将电阻的…

前端css--导航栏效果

效果如下&#xff1a; <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>导航栏动态效果</title><link rel"stylesheet" href"./style/style.css"> </head> &…

51单片机:数码管和矩阵按键

目录 一:动态数码管模块 1:介绍 2:共阴极和共阳极 A:共阴极 B:共阳极 C:转化表 3:74HC138译码器 4:74HC138译码器控制动态数码管 5:数码管显示完整代码 二:矩阵按键模块 1:介绍 2:原理图 3:矩阵按键代码 一:动态数码管模块 1:介绍 LED数码管&#xff1a;数码管是一种…

【数字IC】芯片产业链

芯片产业链 FoundaryFablessEDADesign ServiceIP供应商IDM就业岗位 Foundary Fabless 无晶圆厂 IC design house EDA Design Service Veri Silicon &#xff1a; 芯原微 Alchip&#xff1a;世芯&#xff08;上海&#xff09; Brite&#xff1a;灿芯&#xff08;上海&…

Vue+ElementUI操作确认框及提示框的使用

在进行数据增删改查操作中为保证用户的使用体验&#xff0c;通常需要显示相关操作的确认信息以及操作结果的通知信息。文章以数据的下载和删除提示为例进行了简要实现&#xff0c;点击下载以及删除按钮&#xff0c;会出现对相关信息的提示&#xff0c;操作结果如下所示。 点击…

“数字化员工”,正在占领厂区

劳动力规模逐年降低、劳动生产率增速被平均工资增速超越——中国企业正在面临用工难题。为了应对这一困境&#xff0c;唯一的解决方案就是全面转向“第四种用工模式”——“数字化劳动力”&#xff0c;它可以全力激活人效潜能&#xff0c;并助力企业行稳致远。 智能中央立库中的…

放射组学增强的深度多任务学习用于头颈癌预后预测

文章目录 Radiomics-enhanced Deep Multi-task Learning for Outcome Prediction in Head and Neck Cancer摘要本文方法实验结果 Predicting Regions of Local Recurrence in Glioblastomas Using Voxel-Based Radiomic Features of Multiparametric Postoperative MRI摘要方法…

猿人学第二题—混淆 动态cookie检测

猿人学第二题—混淆 动态cookie检测 1、代码格式化检测2、检测global和navigator.vendorSub3、检测setInterval思考 4、console.log输出检测补环境 简单的document.cookie&#xff0c;location.reload等就不写了 1、代码格式化检测 这里应该是利用了字符串正则匹配性能低的特点…

管理类联考——写作——素材篇——论说文——可持续发展——食蚁兽

巴西热带雨林中的食蚁兽在捕食时&#xff0c;使用带粘液的长舌伸进蚁穴捕获白蚁&#xff0c;但不管捕获多少&#xff0c;每次捕食都不超过3分钟&#xff0c;然后去寻找下一个目标&#xff0c;从来不摧毁整个蚁穴。而那些没有被食蚁兽捕获的工蚁就会修复蚁穴&#xff0c;蚁后也会…

【C++进阶之路】继承篇

文章目录 前言一、概念二、性质1.赋值转换2.作用域——隐藏/重定义3.默认成员函数①构造函数②拷贝构造③析构函数④赋值重载 4.友元函数5.多继承①单继承—— "一脉单传"②多继承——"一父多子"③菱形继承—— "一子多父"④菱形虚拟继承 三、总…

【数据分享】1999—2021年地级市固定资产投资和对外经济贸易数据(Shp/Excel格式)

在之前的文章中&#xff0c;我们分享过基于2000-2022年《中国城市统计年鉴》整理的1999-2021年地级市的人口相关数据、各类用地面积数据、污染物排放和环境治理相关数据、房地产投资情况和商品房销售面积、社会消费品零售总额和年末金融机构存贷款余额、地方一般公共预算收支状…

第二十章 原理篇:CLIP

参考教程&#xff1a; 【PDF】Learning Transferable Visual Models From Natural Language Supervision https://github.com/openai/CLIP 文章目录 概述方法自然语言监督创建一个足够大的数据集选择高效的预训练方法代码解读 选择和缩放模型训练使用 代码解读model load rel…

软件测试:单点登录之—单点流程

用户认证中心采用票据传递的方式进行用户信息共享&#xff0c;保证登录会话在不同的站点进行创建。用户访问目标站点时通过当前登录的站点创建票据&#xff0c;传递票据到目标站点&#xff0c;目标站点接收到票据之后调用用户中心认证系统接口进行票据认证&#xff0c;认证成功…

【C语言15】单链表,(对于二级指针与一级指针应用的详细讲述)

文章目录 单链表1.单链表的介绍2.单链表的实现2.1.1单链表结点的创建与销毁2.1.2单链表尾插2.1.3单链表打印2.1.4尾删2.1.5头插2.1.6头删2.1.7查找2.1.8在pos位置之后插入数据2.1.9删除pos位置 单链表 1.单链表的介绍 链表是一种物理存储结构上非连续、非顺序的存储结构&#…

科学家用ChatGPT写完1篇论文仅用1小时!多所高校撤销禁令

自2022年11月发布以来&#xff0c;许多人都在使用ChatGPT来帮助他们完成工作&#xff0c;各行各业的人都在使用&#xff0c;从撰写营销材料&#xff0c;到起草电子邮件&#xff0c;再到生成报告。 ChatGPT作为一种人工智能工具&#xff0c;在科研中也显示非常大的应用潜力&…

汽车行业 Y 公司对接斯堪尼亚 SCANIA EDI 项目案例

斯堪尼亚是一家来自瑞典的重型车辆制造公司&#xff0c;成立于1891年&#xff0c;总部位于斯德哥尔摩&#xff0c;主要专注于生产卡车、客车和工业发动机&#xff0c;以及相应的服务与解决方案。斯堪尼亚的产品以其高品质、可靠性和先进技术而闻名。其卡车广泛应用于货运和运输…