解析 .Net Core 注入——注册服务

|
interface ITransient { }
class Transient : ITransient { }
interface ISingleton { }
class Singleton : ISingleton { }
interface IScoped { }
class Scoped : IScoped { }
class Program
{
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
services = services.AddTransient<ITransient, Transient>();
services = services.AddScoped<IScoped, Scoped>();
services = services.AddSingleton<ISingleton, Singleton>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
Console.WriteLine(ReferenceEquals(serviceProvider.GetService<ITransient>(), serviceProvider.GetService<ITransient>()));
Console.WriteLine(ReferenceEquals(serviceProvider.GetService<IScoped>(), serviceProvider.GetService<IScoped>()));
Console.WriteLine(ReferenceEquals(serviceProvider.GetService<ISingleton>(), serviceProvider.GetService<ISingleton>()));
IServiceProvider serviceProvider1 = serviceProvider.CreateScope().ServiceProvider;
IServiceProvider serviceProvider2 = serviceProvider.CreateScope().ServiceProvider;
Console.WriteLine(ReferenceEquals(serviceProvider1.GetService<IScoped>(), serviceProvider1.GetService<IScoped>()));
Console.WriteLine(ReferenceEquals(serviceProvider1.GetService<IScoped>(), serviceProvider2.GetService<IScoped>()));
Console.WriteLine(ReferenceEquals(serviceProvider1.GetService<ISingleton>(), serviceProvider2.GetService<ISingleton>()));
/* False
* True
* True
* True
* False
* True
*/
}
}
|
|
public interface IServiceCollection : IList<ServiceDescriptor>
{
}
|
|
public class ServiceDescriptor
{
public ServiceLifetime Lifetime { get; }
public Type ServiceType { get; }
public Type ImplementationType { get; }
public object ImplementationInstance { get; }
public Func<IServiceProvider, object> ImplementationFactory { get; }
}
|
|
public static IServiceCollection AddTransient<TService, TImplementation>(this IServiceCollection services)
where TService : class
where TImplementation : class, TService
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
return services.AddTransient(typeof(TService), typeof(TImplementation));
}
|
|
public enum ServiceLifetime
{
Singleton,
Scoped,
Transient
}
|
|
public class MyServiceProvider : IServiceProvider
{
private List<ServiceDescriptor> serviceDescriptors = new List<ServiceDescriptor>();
private Dictionary<Type, object> SingletonServices = new Dictionary<Type, object>();
public MyServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors)
{
this.serviceDescriptors.AddRange(serviceDescriptors);
}
public object GetService(Type serviceType)
{
var descriptor = serviceDescriptors.FirstOrDefault(t => t.ServiceType == serviceType);
if(descriptor == null)
{
throw new Exception($"服务‘{serviceType.Name}’未注册");
}
else
{
switch (descriptor.Lifetime)
{
case ServiceLifetime.Singleton:
if (SingletonServices.TryGetValue(descriptor.ServiceType,out var obj))
{
return obj;
}
else
{
var singletonObject = Activator.CreateInstance(descriptor.ImplementationType);
SingletonServices.Add(descriptor.ServiceType, singletonObject);
return singletonObject;
}
case ServiceLifetime.Scoped:
throw new NotSupportedException($"创建失败,暂时不支持 Scoped");
case ServiceLifetime.Transient:
var transientObject = Activator.CreateInstance(descriptor.ImplementationType);
return transientObject;
default:
throw new NotSupportedException("创建失败,不能识别的 LifeTime");
}
}
}
}
public static class ServiceCollectionContainerBuilderExtensions
{public static MyServiceProvider BuildeMyServiceProvider(this IServiceCollection services)
{
return new MyServiceProvider(services);
}
}
|
|
case ServiceLifetime.Singleton:
if (SingletonServices.TryGetValue(descriptor.ServiceType,out var obj))
{
return obj;
}
else
{
if(descriptor.ImplementationType != null)
{
var singletonObject = Activator.CreateInstance(descriptor.ImplementationType);
SingletonServices.Add(descriptor.ServiceType, singletonObject);
return singletonObject;
}
else if(descriptor.ImplementationInstance != null)
{
SingletonServices.Add(descriptor.ServiceType, descriptor.ImplementationInstance);
return descriptor.ImplementationInstance;
}
else if(descriptor.ImplementationFactory != null)
{
var singletonObject = descriptor.ImplementationFactory.Invoke(this);
SingletonServices.Add(descriptor.ServiceType, singletonObject);
return singletonObject;
}
else
{
throw new Exception("创建服务失败,无法找到实例类型或实例");
}
}
|
|
public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback
{
private readonly IServiceProviderEngine _engine;
internal ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options)
{
//此处省略了一些代码
switch (options.Mode)
{
case ServiceProviderMode.Dynamic:
_engine = new DynamicServiceProviderEngine(serviceDescriptors, callback);
break;
//此处省略了一些代码
default:
throw new ArgumentOutOfRangeException(nameof(options.Mode));
}
}
public object GetService(Type serviceType) => _engine.GetService(serviceType);
public void Dispose() => _engine.Dispose();
}
|
|
internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory
{
internal CallSiteFactory CallSiteFactory { get; }
protected ServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback)
{
//省略了一些代码
CallSiteFactory = new CallSiteFactory(serviceDescriptors);
CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite());
CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite());
}
}
|
|
internal class CallSiteFactory
{
private readonly List<ServiceDescriptor> _descriptors;
private readonly Dictionary<Type, IServiceCallSite> _callSiteCache = new Dictionary<Type, IServiceCallSite>();
private readonly Dictionary<Type, ServiceDescriptorCacheItem> _descriptorLookup = new Dictionary<Type, ServiceDescriptorCacheItem>();
private struct ServiceDescriptorCacheItem
{
private ServiceDescriptor _item;
private List<ServiceDescriptor> _items;
//省略了一些代码
}
}
internal interface IServiceCallSite
{
Type ServiceType { get; }
Type ImplementationType { get; }
}
|
|
public void Add(Type type, IServiceCallSite serviceCallSite)
{
_callSiteCache[type] = serviceCallSite;
}
|
|
internal class ServiceProviderCallSite : IServiceCallSite
{
public Type ServiceType { get; } = typeof(IServiceProvider);
public Type ImplementationType { get; } = typeof(ServiceProvider);
}
internal class ServiceScopeFactoryCallSite : IServiceCallSite
{
public Type ServiceType { get; } = typeof(IServiceScopeFactory);
public Type ImplementationType { get; } = typeof(ServiceProviderEngine);
}
|
|
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
var serviceProvider = services.BuildServiceProvider();
Console.WriteLine(ReferenceEquals(serviceProvider.GetService<IServiceProvider>(), serviceProvider.GetService<IServiceProvider>()));
var serviceProvider1 = serviceProvider.CreateScope().ServiceProvider;
var serviceProvider2 = serviceProvider.CreateScope().ServiceProvider;
Console.WriteLine(ReferenceEquals(serviceProvider1.GetService<IServiceProvider>(), serviceProvider2.GetService<IServiceProvider>()));
var serviceProvider3 = serviceProvider.GetService<IServiceProvider>();
var serviceProvider4 = serviceProvider.GetService<IServiceProvider>();
var serviceProvider3_1 = serviceProvider3.GetService<IServiceProvider>();
var serviceProvider4_1 = serviceProvider4.GetService<IServiceProvider>();
Console.WriteLine(ReferenceEquals(serviceProvider3,serviceProvider4));
Console.WriteLine(ReferenceEquals(serviceProvider3_1, serviceProvider4_1));
Console.WriteLine(ReferenceEquals(serviceProvider3, serviceProvider3_1));
Console.WriteLine(ReferenceEquals(serviceProvider3,serviceProvider));
/* True
* False
* True
* True
* True
* False
*/
}
|
解析 .Net Core 注入——注册服务的更多相关文章
- 解析 .Net Core 注入 (1) 注册服务
在学习 Asp.Net Core 的过程中,注入可以说是无处不在,对于 .Net Core 来说,它是独立的一个程序集,没有复杂的依赖项和配置文件,所以对于学习 Asp.Net Core 源码的朋友来 ...
- 解析 .Net Core 注入 (3) 创建对象
回顾 通过前两节的学习,我们知道 IServiceCollection 以元数据(ServiceDescriptor)的形式存放着用户注册的服务,它的 IServiceCollection 的拓展方法 ...
- 解析 .Net Core 注入 (2) 创建容器
在上一节的学习中,我们已经知道了通过 IServiceCollection 拓展方法创建 IServiceProvider 默认的是一个类型为 ServiceProvider 对象,并且实际提供创建对 ...
- .Net Core 注入学习——注册服务
解析 .Net Core 注入——注册服务发表于:2017-10-23 10:47 作者:行走即歌 来源:51Testing软件测试网采编字体:大 中 小 | 上一篇 | 下一篇 |我要投稿 | 推荐 ...
- 依赖注入[7]: .NET Core DI框架[服务注册]
包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象.服务注册就是创建出现相应的ServiceDescriptor对象并将其添加到 ...
- .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]
原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...
- 自动注册服务NET Core扩展IServiceCollection
NET Core扩展IServiceCollection自动注册服务 前言 在ASP.NET Core中使用依赖注入中使用很简单,只需在Startup类的ConfigureServices()方法中, ...
- 依赖注入[8]: .NET Core DI框架[服务消费]
包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象.当需要消费某个服务实例的时候,我们只需要指定服务类型调用IServicePr ...
- Asp.net core 向Consul 注册服务
Consul服务发现的使用方法:1. 在每台电脑上都以Client Mode的方式运行一个Consul代理, 这个代理只负责与Consul Cluster高效地交换最新注册信息(不参与Leader的选 ...
随机推荐
- python基础篇_001_初识Python
一.Python环境 windows环境安装Python步骤 .下载安装包:https://www.python.org/downloads/windows/ .安装:默认安装路径:C:\pytho ...
- Django 学习第十天——状态保持及表单
状态保持: 1.http协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态 2.客户端与服务器端的一次通信,就是一次会话实现状态保持的方式:在客户端或服务器端存储与会话有关的数据 3.存 ...
- python数据结构之选择排序
选择排序(select_sort)是一个基础排序,它主要通过查找已给序列中的元素的最大或者最小元素,然后将其放在序列的起始位置或者结束位置,并通过多次这样的循环完成对已知序列的排序,在我们对n个元素进 ...
- linux 学习笔记 显示压缩文件 gong.zip 的文件内容
#zip -v gong zip zip info: xxx >删除压缩文件中俄smart.txt 文件 #zip -d gong.zip smart.txt deleting:smart.tx ...
- Spring cloud Eureka错误锦集(二)
最近学习spring cloud,在测试Eureka作为服务注册中心的时候碰到了问题,错误提示如下: "D:\Program\Java\JDK1.8\bin\java" -XX:T ...
- Java并发编程(十四)-- 线程池实现原理
在上一章我们从宏观上介绍了ThreadPoolExecutor,本文将深入解析一下线程池的具体实现原理 原理解析 线程池状态 在ThreadPoolExecutor中定义了一个volatile变量,另 ...
- JavaScript基础笔记(十四)最佳实践
最佳实践 一)松散耦合 1.解耦HTML/JavaScript: 1)避免html种使用js 2)避免js种创建html 2.解耦CSS/JS 操作类 3.解耦应用逻辑和事件处理 以下是要牢记的应用和 ...
- 潭州课堂25班:Ph201805201 django 项目 第三十课 linux 系统迁移 (课堂笔记)
进入虚拟环境, 冷冻 把安装环境放到这个文档中 pip freeze >> requirements.txt 在另一台机器中 pip install -r requirements.txt ...
- linux环境下mongodb启动操作
pkill mongod 进入mongo shell :运行 db.shutdownServer() 1.进入mongo的shell : mongo --port 1008 2.进入bin目录下 m ...
- Java转型
集合转型 通过中间类型List List<String> strs=new ArrayList<>(); List list=(List)strs; List<Objec ...