private void Invoke(InnerAssemblerDescriptor <T>?descriptor, IDictionary <Type, AssemblerDescriptor <T> > autoServices, Action <AssemblerDescriptor <T> > initAction) { if (descriptor is null) { throw new ArgumentNullException(nameof(descriptor)); } switch (descriptor.Status) { case AssembleStatus.Done: return; // 递归中发现挂起的服务那就是有循环依赖 case AssembleStatus.Hangup: throw new KernelAssembleException($"Exists recursive dependencies on {descriptor.ImplementationType}"); } // 在这个类型之前存在依赖项 if (!descriptor.Prevs.IsNullOrEmpty()) { descriptor.Status = AssembleStatus.Hangup; foreach (var item in descriptor.Prevs) { Invoke(autoServices[item] as InnerAssemblerDescriptor <T>, autoServices, initAction); } } initAction(descriptor); descriptor.Status = AssembleStatus.Done; }
public IDictionary <Type, AssemblerDescriptor <T> > Load(IKernelServices kernelServices, IServiceProvider serviceProvider) { if (kernelServices == null) { throw new ArgumentNullException(nameof(kernelServices)); } if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } var type = typeof(T); var instances = serviceProvider.GetServices <T>(); var dic = new Dictionary <Type, AssemblerDescriptor <T> >(); foreach (var instance in instances) { var implementationType = instance.GetType(); var afterAtAttribute = implementationType.GetCustomAttribute <AfterAtAttribute>(false); var beforeAtAttribute = implementationType.GetCustomAttribute <BeforeAtAttribute>(false); var orderAttribute = implementationType.GetCustomAttribute <OrderAttribute>(false); var descriptor = new InnerAssemblerDescriptor <T>( implementationType, afterAtAttribute?.AfterAt, beforeAtAttribute?.BeforeAt, orderAttribute?.Order ?? 0, instance); dic.Add(implementationType, descriptor); } foreach (var item in dic) { if (item.Value.AfterAt is not null && item.Value.AfterAt.IsSubTypeOrEqualsOf(type) && dic.ContainsKey(item.Value.AfterAt)) { item.Value.Prevs.Add(item.Value.AfterAt); dic[item.Value.AfterAt].Nexts.Add(item.Key); } if (item.Value.BeforeAt is not null && item.Value.BeforeAt.IsSubTypeOrEqualsOf(type) && dic.ContainsKey(item.Value.BeforeAt)) { item.Value.Nexts.Add(item.Value.BeforeAt); dic[item.Value.BeforeAt].Prevs.Add(item.Key); } } return(dic); }