回过头来说一下咱们上面展示的代码,被调用执行的地方就是GetService方法里的realizedService.Invoke(serviceProviderEngineScope)的这段代码 。上面的执行逻辑里涉及到了ServiceProviderEngineScope里的几个操作,比如ResolvedServices属性和CaptureDisposable()方法,看一下相关的代码
internal sealed class ServiceProviderEngineScope : IServiceScope, IServiceProvider, IAsyncDisposable, IServiceScopeFactory{ internal IList<object> Disposables => _disposables ?? (IList<object>)Array.Empty<object>(); private bool _disposed; private List<object> _disposables; internal Dictionary<ServiceCacheKey, object> ResolvedServices { get; } public ServiceProviderEngineScope(ServiceProvider provider, bool isRootScope) { ResolvedServices = new Dictionary<ServiceCacheKey, object>(); } internal object CaptureDisposable(object service) { //判断实例是否实现了IDisposable或IAsyncDisposable接口,因为这种需要在当前作用域是否的时候一起释放 if (ReferenceEquals(this, service) || !(service is IDisposable || service is IAsyncDisposable)) { return service; } bool disposed = false; lock (Sync) { //判断当前作用域是否释放 if (_disposed) { disposed = true; } else { //如果满足则添加到_disposables待释放集合,以便作用域释放的时候一起释放 _disposables ??= new List<object>(); _disposables.Add(service); } } //如果当前作用域已经被释放则直接释放当前实例 if (disposed) { //前提是服务实例是实现IDisposable或IAsyncDisposable接口的 if (service is IDisposable disposable) { disposable.Dispose(); } else { Task.Run(() => ((IAsyncDisposable)service).DisposeAsync().AsTask()).GetAwaiter().GetResult(); } ThrowHelper.ThrowObjectDisposedException(); } return service; }}
经验总结扩展阅读
- asp.net core web 解决方案多项目模板制作打包总结
- ubuntu-22.04 树莓派Zero 2 W通过.NET6和libusb操作USB读写
- 上 学习ASP.NET Core Blazor编程系列六——新增图书
- Azure DevOps Pipelines部署.Net Core 应用到Kubernetes
- 记一次 .NET 某企业OA后端服务 卡死分析
- .NET 采用 SkiaSharp 生成二维码和图形验证码及图片进行指定区域截取方法实现
- .Net CLR异常简析
- 记一次 .NET 某电子病历 CPU 爆高分析
- .NET 7 RC 2 发布,倒计时一个月发布正式版
- .NET MAUI 社区工具包 1.3版本发布
