DOTNET CORE源码分析之IServiceCollection、ServiceCollection和ServiceCollectionDescriptorExtensions

2021-04-03 11:25

阅读:562

标签:ansi   ==   esc   ado   clear   sre   move   接口   队列实现   

  首先谈一下IServiceCollection

  IServiceCollection是一个接口,它继承4个父接口,而且是和ServiceDescriptor挂钩,也就是说,它是保存ServiceDescriptor的一个数据结构接口,具体定义如下:

public interface IServiceCollection : IList, ICollection, IEnumerable, IEnumerable

  很明显,IServiceCollection已经具有一般列表的增删改查等基本功能了。

  再谈一下ServiceCollection

  ServiceCollection是一个ServiceDescriptor队列实现类,主要作用是保存ServiceDescriptor对象,并且提供增删改查功能,具体定义如下:

public class ServiceCollection : IServiceCollection, IList, ICollection, IEnumerable, IEnumerable

  ServiceCollection中默认定义了一个已经实例化的List,而且它是私用的,也就是说只能ServiceCollection这个类内部的方法可以使用,就是它来保存具体的ServiceDescriptor对象的,具体如下:

private readonly List _descriptors = new List();

  既然是List,那它也应该是提供列表应该有的功能,具体如下:

/// 
public int Count
{
  get
  {
	return this._descriptors.Count;
  }
}

/// 
public bool IsReadOnly
{
  get
  {
	return false;
  }
}

/// 
public ServiceDescriptor this[int index]
{
  get
  {
	return this._descriptors[index];
  }
  set
  {
	this._descriptors[index] = value;
  }
}

/// 
public void Clear()
{
  this._descriptors.Clear();
}

/// 
public bool Contains(ServiceDescriptor item)
{
  return this._descriptors.Contains(item);
}

/// 
public void CopyTo(ServiceDescriptor[] array, int arrayIndex)
{
  this._descriptors.CopyTo(array, arrayIndex);
}

/// 
public bool Remove(ServiceDescriptor item)
{
  return this._descriptors.Remove(item);
}

/// 
public IEnumerator GetEnumerator()
{
  return (IEnumerator) this._descriptors.GetEnumerator();
}

void ICollection.Add(ServiceDescriptor item)
{
  this._descriptors.Add(item);
}

IEnumerator IEnumerable.GetEnumerator()
{
  return (IEnumerator) this.GetEnumerator();
}

/// 
public int IndexOf(ServiceDescriptor item)
{
  return this._descriptors.IndexOf(item);
}

/// 
public void Insert(int index, ServiceDescriptor item)
{
  this._descriptors.Insert(index, item);
}

/// 
public void RemoveAt(int index)
{
  this._descriptors.RemoveAt(index);
}

  最后介绍一下ServiceCollectionDescriptorExtensions

  ServcieCollectionDescriptorExtensions这个类其实是用于扩展IServiceCollection的,扩展的有添加,删除,替换等功能。

  在添加功能上,主要分为一般添加和指定生命周期添加,一般是先定义了ServiceDescriptor对象,然后再添加到IServiceCollection中,例如:

public static IServiceCollection Add(
      this IServiceCollection collection,
      ServiceDescriptor descriptor)
{
  if (collection == null)
	throw new ArgumentNullException(nameof (collection));
  if (descriptor == null)
	throw new ArgumentNullException(nameof (descriptor));
  collection.Add(descriptor);
  return collection;
}

  再如:

public static void TryAddTransient(this IServiceCollection collection, Type service)
{
  if (collection == null)
	throw new ArgumentNullException(nameof (collection));
  if (service == (Type) null)
	throw new ArgumentNullException(nameof (service));
  ServiceDescriptor descriptor = ServiceDescriptor.Transient(service, service);
  collection.TryAdd(descriptor);
}

  在删除方面,先是根据类型找到对象,然后再删除:

public static IServiceCollection RemoveAll(
      this IServiceCollection collection,
      Type serviceType)
{
  if (serviceType == (Type) null)
	throw new ArgumentNullException(nameof (serviceType));
  for (int index = collection.Count - 1; index >= 0; --index)
  {
	if (collection[index].ServiceType == serviceType)
	  collection.RemoveAt(index);
  }
  return collection;
}

  

DOTNET CORE源码分析之IServiceCollection、ServiceCollection和ServiceCollectionDescriptorExtensions

标签:ansi   ==   esc   ado   clear   sre   move   接口   队列实现   

原文地址:https://www.cnblogs.com/lizhizhang/p/12541762.html


评论


亲,登录后才可以留言!