当前位置: 首页 > news >正文

宣城网站建设费用中国建设工程交易信息网

宣城网站建设费用,中国建设工程交易信息网,如何利用国外的网站开发客户,如何加入百度推广一#xff1a;背景1. 讲故事前几天有位朋友让我有时间分析一下 aspnetcore 中为什么向 ServiceCollection 中注入的 Class 可以做到 Singleton#xff0c;Transient#xff0c;Scoped#xff0c;挺有意思#xff0c;这篇就来聊一聊这一话题#xff0c;自从 core 中有了 S… 一背景1. 讲故事前几天有位朋友让我有时间分析一下 aspnetcore 中为什么向 ServiceCollection 中注入的 Class 可以做到 SingletonTransientScoped挺有意思这篇就来聊一聊这一话题自从 core 中有了 ServiceCollection, 再加上流行的 DDD 模式相信很多朋友的项目中很少能看到 new 了好歹 spring 十几年前就是这么干的。二Singleton,Transient,Scoped 基本用法分析源码之前我觉得有必要先介绍一下它们的玩法为方便演示我这里就新建一个 webapi 项目定义一个 interface 和 concrete 代码如下 public class OrderService : IOrderService {private string guid;public OrderService(){ guid $时间:{DateTime.Now}, guid{ Guid.NewGuid()}; }public override string ToString(){return guid; } }public interface IOrderService { }1. AddSingleton正如名字所示它可以在你的进程中保持着一个实例也就是说仅有一次实例化不信的话代码演示一下哈。public class Startup {public void ConfigureServices(IServiceCollection services){ services.AddControllers(); services.AddSingleton(); } } [ApiController] [Route([controller])]public class WeatherForecastController : ControllerBase { IOrderService orderService1; IOrderService orderService2;public WeatherForecastController(IOrderService orderService1, IOrderService orderService2){this.orderService1 orderService1;this.orderService2 orderService2; } [HttpGet]public string Get(){ Debug.WriteLine(${this.orderService1}\r\n{this.orderService2} \r\n ------);return helloworld; } }接着运行起来多次刷新页面如下图可以看到不管你怎么刷新页面guid都是一样说明确实是单例的。2. AddScoped正从名字所述Scope 就是一个作用域那在 webapi 或者 mvc 中作用域是多大呢对的就是一个请求当然请求会穿透 Presentation, Application, Repository 等等各层在穿层的过程中肯定会有同一个类的多次注入那这些多次注入在这个作用域下维持的就是单例如下代码所示public void ConfigureServices(IServiceCollection services){ services.AddControllers(); services.AddScoped(); }运行起来多次刷新页面如下图很明显的看到每次刷 UI 的时候guid都会变而在同一个请求 (scope) 中 guid 是一样的。3. AddTransient前面大家也看到了要么作用域是整个进程要么作用域是一个请求而这里的 Transient 就没有作用域概念了注入一次 实例化一次不信的话上代码给你看呗。public void ConfigureServices(IServiceCollection services){ services.AddControllers(); services.AddTransient(); }从图中可以看到注入一次就 new 一次非常简单吧当然了各有各的应用场景。之前不清楚的朋友到现在应该也明白了这三种作用域接下来继续思考的一个问题就是这种作用域是如何做到的呢要想回答这个问题只能研究源代码了。三源码分析aspnetcore 中的 IOC 容器是 ServiceCollection你可以向 IOC 中注入不同作用域的类最后生成 provider如下代码所示var services new ServiceCollection(); services.AddSingleton();var provider services.BuildServiceProvider();1. AddSingleton 的作用域是如何实现的通常说到单例大家第一反应就是 static但是一般 ServiceCollection 中会有成百上千个 AddSingleton 类型都是静态变量是不可能的既然不是 static那就应该有一个缓存字典什么的其实还真的有这么一个。1)RealizedServices 字典每一个 provider 内部都会有一个 叫做 RealizedServices 的字典这个 字典 将会在后面充当缓存存在 如下图从上图中可以看到初始化的时候这个字典什么都没有接下来执行 var orderService provider.GetService(); 效果如下图可以看到 RealizedServices 中已经有了一个 service 记录了接着往下执行 var orderService2 provider.GetService();最终会进入到 CallSiteRuntimeResolver.VisitCache 方法判断实例是否存在如下图仔细看上面代码的这句话: if (!resolvedServices.TryGetValue(callSite.Cache.Key, out obj)) 一旦字典存在就直接返回否则就要执行 new 链路也就是 this.VisitCallSiteMain。综合来看这就是为什么可以单例的原因如果不明白可以拿 dnspy 仔细琢磨琢磨。。。2. AddTransient 源码探究前面大家也看到了provider 里面会有一个 DynamicServiceProviderEngine 引擎类引擎类中用 字典缓存 来解决单例问题可想而知AddTransient 内部肯定是没有字典逻辑的到底是不是呢调试一下呗。和单例一样最终解析都是由 CallSiteRuntimeResolver 负责的AddTransient 内部会走到 VisitDisposeCache 方法而这里会一直走 this.VisitCallSiteMain(transientCallSite, context) 来进行 实例的 new 操作还记得单例是怎么做的吗它会在这个 VisitCallSiteMain 上包一层 resolvedServices 判断? 继续追一下 VisitCallSiteMain 方法吧这个方法最终会走 CallSiteKind.Constructor 分支调用你的构造函数,代码如下protected virtual TResult VisitCallSiteMain(ServiceCallSite callSite, TArgument argument){switch (callSite.Kind) {case CallSiteKind.Factory:return this.VisitFactory((FactoryCallSite)callSite, argument);case CallSiteKind.Constructor:return this.VisitConstructor((ConstructorCallSite)callSite, argument);case CallSiteKind.Constant:return this.VisitConstant((ConstantCallSite)callSite, argument);case CallSiteKind.IEnumerable:return this.VisitIEnumerable((IEnumerableCallSite)callSite, argument);case CallSiteKind.ServiceProvider:return this.VisitServiceProvider((ServiceProviderCallSite)callSite, argument);case CallSiteKind.ServiceScopeFactory:return this.VisitServiceScopeFactory((ServiceScopeFactoryCallSite)callSite, argument); }throw new NotSupportedException(string.Format(Call site type {0} is not supported, callSite.GetType())); }最终由 VisitConstructor 对我的实例代码的构造函数进行调用所以你应该理解了为啥每次注入都会new一次。如下图3. AddScoped 源码探究当你明白了 AddSingleton AddTransient 的原理我想 Scoped 也是非常容易理解的肯定是一个 scoped 一个 RealizedServices 对吧不信的话继续上代码哈。static void Main(string[] args){var services new ServiceCollection(); services.AddScoped();var provider services.BuildServiceProvider();var scoped1 provider.CreateScope();var scoped2 provider.CreateScope();while (true) {var orderService scoped1.ServiceProvider.GetService();var orderService2 scoped2.ServiceProvider.GetService(); Console.WriteLine(orderService); Thread.Sleep(1000); } }然后看一下 scoped1 和 scoped2 是不是都存在独立的缓存字典。从图中可以看到scoped1 和 scoped2 中的 ResolvedServices 拥有不用的count也就说明两者是独立存在的相互不影响。四总结很多时候大家都这么习以为常的用着突然有一天被问起还是有点懵逼的所以时常多问自己几个为什么还是很有必要的哈???。
http://www.zqtcl.cn/news/866824/

相关文章:

  • 惠州建设工程交易网站网站服务器失去响应
  • 网站下拉广告iphone app wordpress
  • 网站图片怎样做seo优化如何重新安装wordpress
  • python做网站源码长沙建设网站制作
  • wordpress调用分类的所有子目录龙岩seo公司首荐3火星
  • 聊城市建设工程质量监督站网站wordpress 头部
  • 低价郑州网站建设wordpress是外网吗
  • 互联网门户网站有哪些win10优化大师是官方的吗
  • 深圳品牌做网站公司有哪些公司名称变更网站要重新备案吗
  • 网站网页建设实训心得体会二类电商平台都有哪些
  • 兰州免费网站建设上海城隍庙要门票吗
  • 如何做外贸soho做网站中型网站建设
  • 冠县品牌网站建设推广外贸企业网站管理系统
  • 信息管理的基本原理分析网站建设南阳网站建设制作
  • 网站一直百度上搜不到是怎么回事啊网站建设首保服务
  • 解决网站兼容性问题福州房产网站建设
  • 怀化百度整站优化服务wap网站前景
  • 临沂制作网站企业施工企业汛期工作实施方案
  • 82家合法现货交易所名单永康关键词优化
  • 郑州市建设工程造价信息网站浙江省建设工程质量管理协会网站
  • 乌兰浩特市建设局网站永州微网站建设
  • 做网站的用什么电脑好wordpress首页调用指定分类
  • 网站域名申请好了怎么建设网站室内设计培训班哪个学校好
  • 东莞厚街网站建设网页设计代码字号px
  • 网站建站免费淘宝优惠券网站建设总代
  • 茶叶网站设计建设工程监理招标网站
  • 网站建设发展历程做网站要多少钱 知乎
  • 丽江建设信息网站江门网站制作方案
  • 网站名注册移动端应用开发
  • 本地网站搭建流程短链接生成器app