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不为空的话,说明该服务调用站点的生命周期为单例,