Asp.net core自定义依赖注入容器,替换自带容器
依赖注入
在asp.net core程序中,众所周知,依赖注入基本上贯穿了整个项目,以通用的结构来讲解,控制器层(Controller层)依赖业务层(Service层),业务层依赖于仓储层(Repository层),而其他层级中也或多或少的使用了依赖注入,在这里不过多的对于依赖注入概念上不进行讲解,如果有不了解的同学,可以在微软官网或者在搜索引擎搜索依赖注入相关概念,本文主要讲解如何在asp.net core中实现自己的依赖注入容器,并且希望更多的同学能够去阅读源码码,因为源码中暴露的一些抽象类或者接口向开发者提供了方便开发者自定义或者拓展的口子。好了,不多啰嗦,我们开始。
First IServiceProviderFactory接口
用过Autofac的同学都知道在asp.net core3版本之后,Autofac的使用方式稍微发生了一些变化,首先需要在Program.cs文件中需要使用Host.UseServiceProviderFactory方法,那实际上这个方法就是让开发者能够去实现自定义的依赖注入容器的一个拓展方法,我们可以查看一下这个方法的定义,注意看有个重点的接口就是IServiceProviderFactory接口,这个接口实际上是指定服务提供者的一个抽象工厂泛型接口,这是实现自定义IOC中最重要的接口之一,也是最开始的一步,实际上,实现自定义依赖注入容器,只需要实现两个接口就可以实现自定义容器,可以看到这个方法有两种参数机制一种是直接传入对应的 实现类,另一种是使用委托的方式去创建对象,并且传入了一个HostBuilderContext的对象,我们会使用这种方式去实现。

Second IServiceProvider接口



我们可以看到这个IServiceProviderFactory接口有两个实现方法,一个是CreateBuilder方法,里面传入IServiceCollection变量,另一个方法是CreateServiceProvider方法,传入我们这个接口指定的容器类的对象,其中IocContainer类不依赖于任何一个抽象,第一个方法的作用就是去构造这个容器的对象,需要返回我们指定的类型的对象,即是这个类是代表着容器,存放服务的,第二个方法是将上面构造的容器对象传入进来,并且返回我们指定的服务提供者,那概念很清晰了,第一个IServiceProviderFactory接口是用来指定我们的容器是哪一个类是我们的容器,以及哪一个是我们的服务提供者,那实际上的IServiceProvider就是第二个重要的一个接口了,这个接口是只有一个方法,GetService方法,参数是一个Type,代表着我们是要去获取哪一个类型的参数,返回值是Object,返回下层依赖者所需要的具体的一个对象。

Three 遵循规则实现自定义容器
那实际上自带的依赖注入容器也是遵循这种规则去实现的,它提供了一个自带的一个ServiceProvider的类去创建对象,那大家都知道启动一个Core的一个程序,自带的一些依赖对象都有一百多个,那大家可能会觉得,让自己去写这种一百多个对象的创建,并且类别还是core的开发者所没有暴露出的类型,创建起来会很麻烦,并且还存在各种依赖,让大家觉得可能自定义依赖注入容器可能很难,实际上,刚开始的时候我也是这么想的,表达式树在我去年十二月份的时候就开始写代码了,只是今年才上传到博客,那实际上,自定义容器我也是去年开始研究的,刚开始也是写了很多判断因为它内部启动的时候大的依赖了两个东西一个是配置的IConfiguration,还有一个就是一个Host的一个类,下面又依赖了很多很多的类,感觉创建起来很麻烦,后来在想到了反射是可以获取程序运行时的元数据并且去构造某个类型,那实际上,我们是可以用反射去实现一种投机取巧的方式去实现自定义依赖注入容器,那就是将启动所依赖服务由自带的ServiceProvider去进行提供和创建,一些项目开发中使用的服务由我们去进行管理,那说到这,已经有很多同学知道了怎么去进行了,我们看代码。

上图中,我们可以看到Provider类是实现了IServiceProvider的接口,并且实现了GetService的方法,可以看到,我使用的方式是去用反射去获取自带的ServiceProvider的构造函数,然后创建这个对象,并且在GetService方法中,首先去判断能否从自带的Provider去获取和创建对象,如果获取不到,那说明是我们项目中所需要的类型,从而使用我们自定义的容器去进行获取对象,默认的获取不到是因为我们在创建ServiceProvider对象的时候传入了IServiceCollection的对象,这里所包含的就是启动Core程序所需要的依赖的集合,这样我们就可以保证,程序启动的时候是可以正常启动的,然后在运行中,请求中所需要的服务类型是由我们自己去创建对象的,所以这样就实现了简单的IOC依赖注入容器,并且替换掉自带的容器。
Four 控制器层的属性注入以及拓展容器实现属性注入和一接口多实现
按照我文章刚开始的时候所说,微软给我们暴露了很多供我们自定义的接口和 抽象类,那如果需要在控制器层实现属性注入那怎么办呢?那实际上还有一个接口,用来让我们去创建控制器,那就是IControllerFactory接口,这个接口有两个方法,一个是CreateController方法和ReleaseController方法,顾名思义就是一个是创建控制器,一个是销毁控制器,那我们可以在第一个方法去实现控制器层的属性注入以及一个接口多实现该怎么去获取的思路,如果是属性注入,我们是需要去创建一个特性用来标记这个属性是用来从容器中获取对象的,我们可以在控制器层或者其他类中使用类似的方法去操作属性注入赋值,如果是一个接口多实现呢,也是需要去定义两个特性,一个特性标记在实现类上面,并且构造函数中有一个string类型的参数,用来标记是在容器中 注入的时候使用某个名称用来标识这个类型,其次在我们进行获取这个类型的时候需要在参数或者属性用我们定义的第二个特性标记这个参数或者属性是从容器中获取的是哪一个名称哪一个类型的对象,这样就可以实现一个属性注入和一个接口多实现的一个操作。

总结
以上是我个人实现自定义IOC的一个解决思路,并且在net core5以及net core6中实现,且5到6实现了无缝升级,没有任何错误,希望能够对各位读者有所帮助。还是希望众多道友能够多解读源码,去查看core框架开发者提供给我们暴露给我们的自定义拓展的一些接口和抽象类。后面我依旧会持续更新core自定义相关的东西,会包括配置还有日志等其他方面的东西,多线程方面的代码已经写完,可以在QQ群6406277群文件中进行查找,也可以查看哪个net群有叫四川观察的,那个就是我。IL后面我也写了很多东西,后续也会一一奉上。在此,谢谢各位看官浏览。

Asp.net core自定义依赖注入容器,替换自带容器的更多相关文章
- ASP.NET Core之依赖注入
本文翻译自:http://www.tutorialsteacher.com/core/dependency-injection-in-aspnet-core ASP.NET Core支持依赖注入,依赖 ...
- 几十行代码实现ASP.NET Core自动依赖注入
在开发.NET Core web服务的时候,我们习惯使用自带的依赖注入容器来进行注入. 于是就会经常进行一个很频繁的的重复动作:定义一个接口->写实现类->注入 有时候会忘了写Add这一步 ...
- 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类
依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来.服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了依 ...
- ASP.NET Core:依赖注入
ASP.NET Core的底层设计支持和使用依赖注入.ASP.NET Core应用程序可以利用内置的框架服务将它们注入到启动类的方法中,并且应用程序服务能够配置注入.由ASP.NET Core提供的默 ...
- asp.net core ioc 依赖注入
1.生命周期 内置的IOC有三种生命周期: Transient: Transient服务在每次被请求时都会被创建.这种生命周期比较适用于轻量级的无状态服务. Scoped: Scoped生命周期的服务 ...
- 用工厂模式解决ASP.NET Core中依赖注入的一个烦恼
这是最近在实际开发中遇到的一个问题,用 asp.net core 开发一个后端 web api ,根据指定的 key 清除 2 台 memcached 服务器上的缓存.背景是我们在进行 .net co ...
- ASP.NET Core依赖注入系统学习教程:容器对构造函数选择的策略
.NET Core的依赖注入容器之所以能够为应用程序提供服务实例,这都归功于ServiceDescriptor对象提供的服务注册信息.另外,在ServiceDescriptor对象中,还为容器准备了3 ...
- asp.net core 自定义 Policy 替换 AllowAnonymous 的行为
asp.net core 自定义 Policy 替换 AllowAnonymous 的行为 Intro 最近对我们的服务进行了改造,原本内部服务在内部可以匿名调用,现在增加了限制,通过 identit ...
- 【半小时大话.net依赖注入】(下)详解AutoFac+实战Mvc、Api以及.NET Core的依赖注入
系列目录 上|理论基础+实战控制台程序实现AutoFac注入 下|详解AutoFac+实战Mvc.Api以及.NET Core的依赖注入 前言 本来计划是五篇文章的,每章发个半小时随便翻翻就能懂,但是 ...
随机推荐
- Dubbo与Zookeeper简单理解
理论 在<分布式系统原理与范型>一书中有如下定义:"分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统 "; 分布式系统是由一组通过网络进行通信. ...
- JavaScript数组 几个常用方法
前言 数组方法有太多了,本文记录一些本人容易记错的一些数组方法,用于巩固及复习. 后续会慢慢的将其他数组方法添加进来. 善用数组方法可以使数据处理变的优雅且简单. 那下面让我们开始吧: filter( ...
- 关于web项目中的资源跳转
1.跳转包括两种方式: 转发 forward 重定向 redirect 2.两种方式的代码: AServlet类: //向request范围中存储数据 request.setAttribute(&qu ...
- 浏览器有别_HTTP报文的回车换行
本来以为浏览器HTTP报文的生成应该是完全一致的.但最近在做一个项目的时候,发现Safari和Chrome提交同一份表单,后端的处理结果不一致.看提交结果呢,是因为Safari多了个回车.由于原项目的 ...
- 【UE4 设计模式】享元模式 Flyweight Pattern
概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...
- Beta发布声明
项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 Beta-发布声明 我们是谁 删库跑路对不队 我们在做什么 题士 进度如何 进度总览 一.功能与特性 1.一 ...
- UltraSoft - Alpha - 发布声明
DDL_Killer Alpha版本发布声明 1. Alpha 阶段功能描述与版本实现 功能描述 设计原型 Alpha实现 登陆界面 注册界面 首页 日历视图 事项详情页 新建事项 列表视图 课程视图 ...
- RSA加密——前端JSEncrypt
RSA加密--前端JSEncrypt 介绍 JSEncrypt是一个RSA加密库,在没有SSL加密传输通道支持https协议的情况下,该库可以在http传输重要信息如时,保证数据的安全性.我们小组 ...
- [火星补锅] siano 神奇的线段树
前言: 本来以为很难打的,没想到主干一次就打对了,然而把输入的b和d弄混了,这sb错误调了两个小时... 解析: 神奇的线段树.注意到有一个性质,无论怎么割草,生长速度快的一定不会比生长速度慢的矮.因 ...
- 详解DNS域名解析系统(域名、域名服务器[根、顶级、授权/权限、本地]、域名解析过程[递归与迭代])
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105583806 学习课程:<2019王道考研计算机网络> 学习目的 ...