解析 .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的选 ...
随机推荐
- 20165235实验四 Android程序设计
20165235实验四 Android程序设计 实验课程:JAVA编程设计 实验名称:Android开发 姓名:祁瑛 学号:20165235 实验时间:2018.05.16 指导老师:娄家鹏 Andr ...
- SEED-DVS6467_SDK的交叉编译环境搭建问题
今天在ubuntu16.04上安装arm的交叉编译器arm_v5t_le-gcc,环境变量配置好以后,运行arm_v5t_le-gcc命令,总提示No such file or directory.然 ...
- Square Destroyer-POJ 1084 (IDA*)
Description The left figure below shows a complete 3*3 grid made with 2*(3*4) (=24) matchsticks. The ...
- Linux命令集
系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecode -q 显示硬件系统部件 - (SMBIOS ...
- vim编辑器第二天
编辑模式的进入: i :在光标所在的字符前插入 a :在光标所在的字符后插入 o :在光标所在的行的下面一行插入 I : 在光标所在的行的行首插入,如果行首有空格则在空格后面开始插入 A :在光标 ...
- 服务注册与发现---eureka
eureka简介:云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移. 话不多说直接上代码 首先新建一个springcloud eurekaserver项目. ...
- JS 实现打印
<input id="btnPrint" type="button" value="打印预览" onclick=preview(1) ...
- react组件通信那些事儿
父组件是调用组件的组件.现在看来,感觉父组件就是一个壳子,定义好壳子里面会有什么,而子组件是一个具体的实现,说明,会用到什么东西,如果有这些东西,会进行什么操作.总之,父组件是材料,有水和泥,子组件告 ...
- BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)
BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...
- bzoj 泛做
3003 这个题是这样的,对序列差分后,每个取反操作就是给两个端点的值取反,然后背包之后再状压就好了 4128 这题棒棒的QAQBSGS 23333 4176 这个杜教筛呃呃呃大爷链接 3028 我要 ...