解析 .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的选 ...
随机推荐
- Linux常用命令行补充——持续更新
1.查看文件夹大小 =>ls -lht 路径 ls -lht /opt/jars 2.查看文件大小 =>du -sh / du -sh /opt/jars/calllog.csv 3.编辑 ...
- Flume配置文件写法总结
一.agent 第一步是定义agent(代理)及agent下的sources.channels.sinks的简称,如下: a1.sources = r1 a1.sinks = k1 a1.channe ...
- CentOS系统找不到setup命令工具的解决方法
如果你的CentOS系统中没有setup命令,很有可能是因为你安装CentOS系统时采用了最小化安装(minimal).这时,你执行setup命令时,就会报错: 错误信息: 1[root@localh ...
- Visual Studio 2019及其注册码
Visual Studio 2019 更快地进行代码编写.更智能地执行操作.使用同类最佳IDE 创建未来. 下载Visual Studio 使用从初始设计到最终部署的完整工具集 ...
- HDU 5036 Explosion (传递闭包+bitset优化)
<题目链接> 题目大意: 一个人要打开或者用炸弹砸开所有的门,每个门后面有一些钥匙,一个钥匙对应一个门,告诉每个门里面有哪些门的钥匙.如果要打开所有的门,问需要用的炸弹数量为多少. 解题分 ...
- Pytorch安装(基于anaconda虚拟环境)
Pytorch安装倒腾了一上午终于搞定,记录一下安装过程. 1. 首先尝试官网的安装方式,但是网速太慢了. 除去cudnn100, torchvision和pytorch三个文件,其余可以直接从清华镜 ...
- 一个简单需求:HashMap实现相同key存入数据后不被覆盖
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 看似是一个简单的问题,其实里面包含很多的东西! 需求: 实现一个在HashMap中存入(任意类型)相同的key值后,key ...
- shell 运算符
shell的逻辑运算符 涉及有以下几种类型,因此只要适当选择,可以解决我们很多复杂的判断,达到事半功倍效果. 一.逻辑运算符 逻辑卷标 表示意思 1. 关于档案与目录的侦测逻辑卷标! -f 常用!侦测 ...
- photoshop实现倾斜图片的修正
第一天学习Photoshop,了解到了Photoshop对图片的处理,下面是实现一个倾斜图片修正的两种方法: 举例图片: 第一种方法:1.利用吸管中的标尺工具量倾斜度数: 2.利用旋转图像,旋转对应的 ...
- asp.net core自定义模型验证——前端验证
转载请注明出处:http://www.cnblogs.com/zhiyong-ITNote/ 官方网站:https://docs.microsoft.com/zh-cn/aspnet/core/mvc ...