DOTNET CORE源码分析之IServiceCollection、ServiceCollection和ServiceCollectionDescriptorExtensions
首先谈一下IServiceCollection
IServiceCollection是一个接口,它继承4个父接口,而且是和ServiceDescriptor挂钩,也就是说,它是保存ServiceDescriptor的一个数据结构接口,具体定义如下:
public interface IServiceCollection : IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable
很明显,IServiceCollection已经具有一般列表的增删改查等基本功能了。
再谈一下ServiceCollection
ServiceCollection是一个ServiceDescriptor队列实现类,主要作用是保存ServiceDescriptor对象,并且提供增删改查功能,具体定义如下:
public class ServiceCollection : IServiceCollection, IList<ServiceDescriptor>, ICollection<ServiceDescriptor>, IEnumerable<ServiceDescriptor>, IEnumerable
ServiceCollection中默认定义了一个已经实例化的List<ServiceDescriptor>,而且它是私用的,也就是说只能ServiceCollection这个类内部的方法可以使用,就是它来保存具体的ServiceDescriptor对象的,具体如下:
private readonly List<ServiceDescriptor> _descriptors = new List<ServiceDescriptor>();
既然是List<ServiceDescriptor>,那它也应该是提供列表应该有的功能,具体如下:
/// <inheritdoc /> public int Count { get { return this._descriptors.Count; } } /// <inheritdoc /> public bool IsReadOnly { get { return false; } } /// <inheritdoc /> public ServiceDescriptor this[int index] { get { return this._descriptors[index]; } set { this._descriptors[index] = value; } } /// <inheritdoc /> public void Clear() { this._descriptors.Clear(); } /// <inheritdoc /> public bool Contains(ServiceDescriptor item) { return this._descriptors.Contains(item); } /// <inheritdoc /> public void CopyTo(ServiceDescriptor[] array, int arrayIndex) { this._descriptors.CopyTo(array, arrayIndex); } /// <inheritdoc /> public bool Remove(ServiceDescriptor item) { return this._descriptors.Remove(item); } /// <inheritdoc /> public IEnumerator<ServiceDescriptor> GetEnumerator() { return (IEnumerator<ServiceDescriptor>) this._descriptors.GetEnumerator(); } void ICollection<ServiceDescriptor>.Add(ServiceDescriptor item) { this._descriptors.Add(item); } IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator) this.GetEnumerator(); } /// <inheritdoc /> public int IndexOf(ServiceDescriptor item) { return this._descriptors.IndexOf(item); } /// <inheritdoc /> public void Insert(int index, ServiceDescriptor item) { this._descriptors.Insert(index, item); } /// <inheritdoc /> 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; }