ASP.NET CORE 默认DI默认实现包分析(DependencyInjectionAbstractions,c#,asp.net,.net,IOC)

DependencyInjection概述

ServiceIdentifier

internal readonly struct ServiceIdentifier : IEquatable<ServiceIdentifier> {
    // service的key标识
		public object? ServiceKey { get; }
		// service的类型
    public Type ServiceType { get; }
  	//创建 携带key标识的service的身份证
  	public static ServiceIdentifier FromDescriptor(ServiceDescriptor serviceDescriptor)
            => new ServiceIdentifier(serviceDescriptor.ServiceKey, serviceDescriptor.ServiceType);
    //创建 不ey标识的service的身份证
    public static ServiceIdentifier FromServiceType(Type type) => new ServiceIdentifier(null, type);

		public ServiceIdentifier(Type serviceType){
         ServiceType = serviceType;
    }
		public ServiceIdentifier(object? serviceKey, Type serviceType){
         ServiceKey = serviceKey; ServiceType = serviceType;
    }
		public ServiceIdentifier GetGenericTypeDefinition() => new ServiceIdentifier(ServiceKey, ServiceType.GetGenericTypeDefinition());
}

服务身份证:身份证构成 serviceKey(key标识) + serviceType

ServiceDescriptorCacheItem

 private struct ServiceDescriptorCacheItem{
 	 //这里存储的是 同一个ServiceIdentifier的多个实现时,第一个注册进来的值
   private ServiceDescriptor? _item;
   //存储 同一个ServiceIdentifier的多个实现,并添加到一起,而他们的顺序就是他们在ServiceCacheKey中的slot(槽位)
   private List<ServiceDescriptor>? _items;
   public ServiceDescriptor Last{
           get{
                if (_items != null && _items.Count > 0){
                      return _items[_items.Count - 1];
                }
              return _item;
            }
  }

   public int Count{
					get{
            	if (_item == null){
                return 0;
              }
							return 1 + (_items?.Count ?? 0);
          }
   }
   
   public ServiceDescriptor this[int index]{
     			get{
            if (index >= Count){
              throw new ArgumentOutOfRangeException(nameof(index));
            }
            if (index == 0){
              return _item!;
            }
            return _items![index - 1];
          }
   }
   
   public int GetSlot(ServiceDescriptor descriptor)
   {
     if (descriptor == _item){
       return Count - 1;
     }
     if (_items != null){
       int index = _items.IndexOf(descriptor);
       if (index != -1){
         return _items.Count - (index + 1);
       }
     }
     throw new InvalidOperationException(SR.ServiceDescriptorNotExist);
   }
   
   public ServiceDescriptorCacheItem Add(ServiceDescriptor descriptor){
     var newCacheItem = default(ServiceDescriptorCacheItem);
     if (_item == null){
       newCacheItem._item = descriptor;
     }
     else{
       newCacheItem._item = _item;
       newCacheItem._items = _items ?? new List<ServiceDescriptor>();
       newCacheItem._items.Add(descriptor);
     }
     return newCacheItem;
   }
 }
}

通过 ServiceDescriptor 中的 ServiceKey 和 ServiceType 去创建出 ServiceIdentifier,再根据ServiceIdentifier是否相同,将相同的ServiceIdentifier的ServiceDescriptor存放在ServiceDescriptorCacheItem中的list集合中,而list集合中的存放顺序实际上就是 ServiceCacheKey上对应的槽位。

ServiceCacheKey

internal readonly struct ServiceCacheKey : IEquatable<ServiceCacheKey> {
       
        public ServiceIdentifier ServiceIdentifier { get; }
        /// 对于同一个 ServiceIdentifier 中有多个实现类
        /// For example for service collection
        ///  IService Impl1
        ///  IService Impl2
        ///  IService Impl3
        /// We would get the following cache keys:
        ///  Impl1 2
        ///  Impl2 1
        ///  Impl3 0
        /// </summary>
        public int Slot { get; }

        public ServiceCacheKey(object key, Type type, int slot){
            ServiceIdentifier = new ServiceIdentifier(key, type);
            Slot = slot;
        }
        public ServiceCacheKey(ServiceIdentifier type, int slot){
            ServiceIdentifier = type;
            Slot = slot;
        }
}

小结

ServiceIdentifier = ServiceDescriptor.serviceKey + ServiceDescriptor.serviceType

ServiceCacheKey = ServiceIdentifier + slot( List.index位置)

ServiceDescriptorCacheItem = List + List[0]

ServiceCallSite(服务调用站点)

internal abstract class ServiceCallSite{
  protected ServiceCallSite(ResultCache cache){
    Cache = cache;
  }
  //服务的类型
  public abstract Type ServiceType { get; }
  //服务的实现可续
  public abstract Type? ImplementationType { get; }
  //调用站点类型
  public abstract CallSiteKind Kind { get; }
  //服务的生命周期,serviceIdentifier(服务身份证)以及服务所在ServiceDescriptorCacheItem-list的位置
  public ResultCache Cache { get; }
  //单例储存的地方
  public object? Value { get; set; }
  public object? Key { get; set; }
}

ConstantCallSite

CallSiteFacory.TryCreateExact方法中可知:

if (descriptor.HasImplementationInstance()){
callSite = new ConstantCallSite(descriptor.ServiceType, descriptor.GetImplementationInstance());
}
//descriptor.HasImplementationInstance()方法最终来到此进行判断,就是判断是否以及存在service的实例
public static object? GetImplementationInstance(this ServiceDescriptor serviceDescriptor)
{
 return serviceDescriptor.IsKeyedService
     ? serviceDescriptor.KeyedImplementationInstance
     : serviceDescriptor.ImplementationInstance;
}
  • 由上可知:
  • ConstantCallSite应用与 serviceDescription 中_implementationInstance不为空的情况
  • 而_implementationInstance不为空的话,说明该服务调用站点的生命周期为单例,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值