/// <summary> /// 递归查找父节点 /// </summary> /// <param name="dependencyInjectionTreeModel"></param> /// <param name="type"></param> /// <returns></returns> private static DependencyInjectionTreeModel GetDependencyInjectionTree(DependencyInjectionTreeModel dependencyInjectionTreeModel, Type type) { if (dependencyInjectionTreeModel == null) { return(null); } if (dependencyInjectionTreeModel.DependencyInjection.Type == type) { return(dependencyInjectionTreeModel); } if (dependencyInjectionTreeModel.ParentDependencyInjectionTree == null) { return(null); } return(GetDependencyInjectionTree(dependencyInjectionTreeModel.ParentDependencyInjectionTree, type)); }
/// <summary> /// 分析依赖树 /// </summary> /// <param name="dependencyInjectionTreeModel"></param> private static void AnalysisDependencyInjectionTree(DependencyInjectionTreeModel dependencyInjectionTreeModel) { foreach (var propertyInfo in dependencyInjectionTreeModel.DependencyInjection.Type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { //判断当前属性是否具有DependencyInjectionAttribute特性 var customeAttribute = propertyInfo.GetCustomAttribute(typeof(AutowiredAttribute), false); if (customeAttribute == null) { continue; } //等待注入的类型 var injectionType = ((AutowiredAttribute)customeAttribute).RealType ?? propertyInfo.PropertyType; //自己依赖自己 if (injectionType == dependencyInjectionTreeModel.DependencyInjection.Type) { throw new UnableResolveDependencyException($"Unable to resolve dependency {injectionType.FullName}."); } //从父树查找是否已经有依赖 var parentInjectionTreeModel = GetDependencyInjectionTree(dependencyInjectionTreeModel.ParentDependencyInjectionTree, injectionType); if (parentInjectionTreeModel != null) { //查找父树的依赖是否是Transient模式,如是则此循环依赖无法支持 if (parentInjectionTreeModel.DependencyInjection.DependencyInjectionMode == DependencyInjectionModeEnum.Transient) { throw new UnableResolveDependencyException($"Unable to resolve dependency {injectionType.FullName}. {parentInjectionTreeModel.DependencyInjection.Type.FullName} DependencyInjectionMode should not be Transient when using circular dependencies"); } continue; } //查看是否加入到了容器 var dependencyInjection = DependencyInjections.FirstOrDefault(item => item.Type == injectionType); if (dependencyInjection == null) { //虽然未找到实例,但是可能通过IServiceCollection加入到了容器 continue; } var nextDependencyInjectionTreeModel = new DependencyInjectionTreeModel { DependencyInjection = dependencyInjection, ParentDependencyInjectionTree = dependencyInjectionTreeModel }; AnalysisDependencyInjectionTree(nextDependencyInjectionTreeModel); } foreach (var fieldInfo in dependencyInjectionTreeModel.DependencyInjection.Type.GetFields(BindingFlags.Public | BindingFlags.NonPublic)) { //判断当前属性是否具有DependencyInjectionAttribute特性 var customeAttribute = fieldInfo.GetCustomAttribute(typeof(AutowiredAttribute), false); if (customeAttribute == null) { continue; } //等待注入的类型 var injectionType = ((AutowiredAttribute)customeAttribute).RealType ?? fieldInfo.FieldType; //自己依赖自己 if (injectionType == dependencyInjectionTreeModel.DependencyInjection.Type) { throw new UnableResolveDependencyException($"Unable to resolve dependency {injectionType.FullName}."); } //从父树查找是否已经有依赖 var parentInjectionTreeModel = GetDependencyInjectionTree(dependencyInjectionTreeModel.ParentDependencyInjectionTree, injectionType); if (parentInjectionTreeModel != null) { //查找父树的依赖是否是Transient模式,如是则此循环依赖无法支持 if (parentInjectionTreeModel.DependencyInjection.DependencyInjectionMode == DependencyInjectionModeEnum.Transient) { throw new UnableResolveDependencyException($"Unable to resolve dependency {injectionType.FullName}. {parentInjectionTreeModel.DependencyInjection.Type.FullName} DependencyInjectionMode should not be Transient when using circular dependencies"); } continue; } //查看是否加入到了容器 var dependencyInjection = DependencyInjections.FirstOrDefault(item => item.Type == injectionType); if (dependencyInjection == null) { //虽然未找到实例,但是可能通过IServiceCollection加入到了容器 continue; } var nextDependencyInjectionTreeModel = new DependencyInjectionTreeModel { DependencyInjection = dependencyInjection, ParentDependencyInjectionTree = dependencyInjectionTreeModel }; AnalysisDependencyInjectionTree(nextDependencyInjectionTreeModel); } }