/// <summary> /// Generate error message which highlights services with circular dependencies. /// </summary> /// <remarks> /// <para>You can check the value of <see cref="HasCircularDependency"/> to /// determine whether circular dependencies hvae been detected before using /// this method.</para> /// </remarks> /// <returns> /// A string containing an error message when circular service dependencies /// have been detected; otherwise, a value of <c>null</c>. /// </returns> /// <seealso cref="HasCircularDependency"/> public string GenerateCircularDependencyErrorMessage() { var sb = new StringBuilder(); sb.AppendLine(CircularDependencyNodes.Count() > 2 ? "Has circular dependencies" : "Has circular dependency"); sb.AppendLine("Select this log entry to see circular dependencies:"); var remainingCircularNodes = new HashSet <ServiceDependencyGraph.Node>(CircularDependencyNodes); while (remainingCircularNodes.Count != 0) { var circularNode = remainingCircularNodes.First(); remainingCircularNodes.Remove(circularNode); sb.AppendLine(); sb.AppendLine(circularNode.Installer.TargetService.ServiceType.FullName); // Produce list of other services that form circular dependency. var circular = new HashSet <ServiceDependencyGraph.Node>(); AddCircularDependencies(circularNode, circular); circular.Remove(circularNode); // Present immediate dependencies first. foreach (var n in circularNode.Targets) { sb.AppendLine(" ➜ " + n.Installer.TargetService.ServiceType.FullName); circular.Remove(n); remainingCircularNodes.Remove(n); } // Then present subsequent dependencies. foreach (var n in circular) { sb.AppendLine(" → " + n.Installer.TargetService.ServiceType.FullName); remainingCircularNodes.Remove(n); } } return(sb.ToString()); }
/// <summary> /// Generate error message which highlights services with circular dependencies. /// </summary> /// <remarks> /// <para>You can check the value of <see cref="HasCircularDependency"/> to /// determine whether circular dependencies hvae been detected before using /// this method.</para> /// </remarks> /// <param name="contextInstaller">Circular dependencies are reported if related /// to the specified context service installer.</param> /// <returns> /// A string containing an error message when circular service dependencies /// have been detected; otherwise, a value of <c>null</c>. /// </returns> /// <exception cref="System.ArgumentNullException"> /// If <paramref name="contextInstaller"/> is a value of <c>null</c>. /// </exception> /// <seealso cref="HasCircularDependency"/> public string GenerateCircularDependencyErrorMessage(IServiceInstaller contextInstaller) { if (contextInstaller == null) { throw new ArgumentNullException("contextInstaller"); } var circularNode = CircularDependencyNodes.FirstOrDefault(n => n.Installer == contextInstaller); if (circularNode != null) { // Produce list of other services that form circular dependency. var circular = new HashSet <ServiceDependencyGraph.Node>(); AddCircularDependencies(circularNode, circular); circular.Remove(circularNode); var sb = new StringBuilder(); sb.AppendLine(circular.Count > 1 ? "Has Circular Dependencies:" : "Has Circular Dependency:"); sb.AppendLine(); // Present immediate dependencies first. foreach (var n in circularNode.Targets) { sb.AppendLine(" ➜ " + n.Installer.TargetService.ServiceType.FullName); circular.Remove(n); } // Then present subsequent dependencies. foreach (var n in circular) { sb.AppendLine(" → " + n.Installer.TargetService.ServiceType.FullName); } return(sb.ToString()); } else { return(null); } }