예제 #1
0
        private static void WriteMainNodeDependants(AssemblyDependencyNode mainNode, AssemblyDependencyGraph graph)
        {
            var mainNodeDependants = graph.GetDirectDependants(mainNode).OrderBy(x => x.Identity).ToList();

            if (mainNodeDependants.Any())
            {
                Logger.Information(Separator);
                Logger.Warning("WARNING: Detected that there are still some assemblies that depend on the main assembly. Try to avoid this scenario. Different binding redirects might be needed for them.");
                foreach (var node in mainNodeDependants)
                {
                    Logger.Information("{AssemblyIdentity}", node.Identity);
                }
            }
        }
예제 #2
0
        private static void WriteNodesOutsideMainDependencyTree(AssemblyDependencyNode mainNode, List <AssemblyDependencyNode> nodes, IList <AssemblyDependencyNode> allMainDependencies, AssemblyDependencyGraph graph)
        {
            var nodesOutsideOfDependencyTree = nodes
                                               .Where(x => x != mainNode && !allMainDependencies.Contains(x))
                                               .Where(x => x.Loaded)
                                               .ToList();

            if (nodesOutsideOfDependencyTree.Any())
            {
                Logger.Information(Separator);
                Logger.Information("All assemblies that aren't in any way connected to the main, but were loaded:");

                foreach (var node in nodesOutsideOfDependencyTree)
                {
                    Logger.Information(Separator);
                    Logger.Warning("{AssemblyIdentity}", node.Identity);

                    var directDependants = graph.GetDirectDependants(node).ToList();
                    if (directDependants.Any())
                    {
                        Logger.Information("");
                        Logger.Information("Nodes that depend on this assembly directly:");
                        foreach (var dependant in directDependants)
                        {
                            Logger.Information("{AssemblyIdentity}", dependant.Identity);
                        }

                        var indirectDependants = graph.GetIndirectDependants(node).ToList();
                        if (indirectDependants.Any())
                        {
                            Logger.Information("");
                            Logger.Information("Nodes that depend on this assembly indirectly:");
                            foreach (var dependant in indirectDependants)
                            {
                                Logger.Information("{AssemblyIdentity}", dependant.Identity);
                            }
                        }
                    }
                    else
                    {
                        Logger.Information("");
                        Logger.Information("No nodes that depend on this were found.");
                    }
                }
            }
        }
예제 #3
0
        private static void WriteAssembliesNotLoaded(List <AssemblyDependencyNode> nodes, AssemblyDependencyGraph graph)
        {
            var nodesByGroup   = nodes.ToLookup(x => x.Identity.Unversioned);
            var nodesNotLoaded = nodes.Where(node => !node.Loaded).ToList();

            if (nodesNotLoaded.Any())
            {
                Logger.Information(Separator);
                Logger.Information("Assemblies that couldn't be loaded:");

                foreach (var node in nodesNotLoaded)
                {
                    Logger.Information(Separator);

                    if (node.Name != null)
                    {
                        Logger.Information("{AssemblyIdentity}", node.Identity);
                    }
                    else
                    {
                        Logger.Information("{File}", node.File.FullName);
                    }

                    Logger.Information("");

                    if (node.LoadedFromName == AssemblyLoadStatus.Failed)
                    {
                        Logger.Information("Couldn't load from assembly name. Exception message:");
                        Logger.Information(node.LoadedFromNameError.Message);
                    }
                    else if (node.LoadedFromFile == AssemblyLoadStatus.Failed)
                    {
                        Logger.Information("Couldn't load from file. Exception message:");
                        Logger.Information(node.LoadedFromFileError.Message);
                    }
                    else
                    {
                        throw new InvalidOperationException("Assembly not attempted to be loaded, something went wrong.");
                    }

                    var directDependants = graph.GetDirectDependants(node).ToList();
                    if (directDependants.Any())
                    {
                        Logger.Information("");
                        Logger.Information("Nodes that depend on this assembly directly:");
                        foreach (var dependant in directDependants)
                        {
                            Logger.Information("{AssemblyIdentity}", dependant.Identity);
                        }

                        var indirectDependants = graph.GetIndirectDependants(node).ToList();
                        if (indirectDependants.Any())
                        {
                            Logger.Information("");
                            Logger.Information("Nodes that depend on this assembly indirectly:");
                            foreach (var dependant in indirectDependants)
                            {
                                Logger.Information("{AssemblyIdentity}", dependant.Identity);
                            }
                        }
                    }
                    else
                    {
                        Logger.Information("");
                        Logger.Information("No nodes that depend on this were found.");
                    }

                    Logger.Information("");
                    Logger.Information("If this is an important reference, consider fixing this reference. Also make sure that you didn't omit it from the inputs.");

                    var otherNodesInGroup = nodesByGroup[node.Identity.Unversioned].Where(x => x != node && x.Loaded).ToList();
                    if (otherNodesInGroup.Any())
                    {
                        Logger.Information("");
                        Logger.Information("Other versions of this assembly were loaded:");
                        foreach (var otherVersionNode in otherNodesInGroup.OrderBy(x => x.Identity.Version))
                        {
                            Logger.Information("{Version}", otherVersionNode.Identity.Version);
                        }

                        if (otherNodesInGroup.All(x => x.Identity.Version < node.Identity.Version))
                        {
                            Logger.Warning("WARNING: This is the highest version of the assembly, yet it wasn't loaded. A downgrading binding redirect might be needed.");
                        }
                    }
                }
            }
        }
예제 #4
0
        private static void WriteBindingRedirects(IList <AssemblyDependencyNode> allMainDependencies, AssemblyDependencyGraph graph)
        {
            var dependenciesGrouped = allMainDependencies
                                      .GroupBy(x => x.Identity.Unversioned)
                                      .Where(x => x.Count() > 1 && x.Any(y => y.Loaded))
                                      .OrderBy(x => x.Key)
                                      .ToList();

            if (dependenciesGrouped.Any())
            {
                Logger.Information(Separator);
                Logger.Information("Recommended binding redirects:");
                var dependentAssemblyTriples = new List <(AssemblyUnversionedIdentity Key, Version highestVersion, Version highestVersionLoaded)>();

                foreach (var group in dependenciesGrouped)
                {
                    Logger.Information(Separator);
                    Logger.Information("{AssemblyName}", group.Key.ToString());

                    Logger.Information("--- Versions ---");
                    foreach (var node in group.OrderBy(x => x.Identity.Version))
                    {
                        Logger.Information("");

                        if (node.Loaded)
                        {
                            Logger.Information("-- {Version} [Location=\"{Location}\"]", node.Identity.Version, node.File.FullName);
                        }
                        else
                        {
                            Logger.Warning("-- {Version} [Not Found]", node.Identity.Version);
                        }

                        var directDependants = graph.GetDirectDependants(node).ToList();
                        if (directDependants.Any())
                        {
                            Logger.Information("");
                            Logger.Information("Nodes that depend on this version directly:");
                            foreach (var dependant in directDependants)
                            {
                                Logger.Information("{AssemblyIdentity}", dependant.Identity);
                            }

                            var indirectDependants = graph.GetIndirectDependants(node).ToList();
                            if (indirectDependants.Any())
                            {
                                Logger.Information("");
                                Logger.Information("Nodes that depend on this version indirectly:");
                                foreach (var dependant in indirectDependants)
                                {
                                    Logger.Information("{AssemblyIdentity}", dependant.Identity);
                                }
                            }
                        }
                        else
                        {
                            Logger.Information("");
                            Logger.Warning("No nodes that depend on this version were found.");
                        }
                    }

                    var highestVersion       = group.Max(x => x.Identity.Version);
                    var highestVersionLoaded = group.Where(x => x.Loaded).Max(x => x.Identity.Version);

                    var dependentAssemblyTriple = (group.Key, highestVersion, highestVersionLoaded);
                    var element = GetAssemblyBindingXElement(dependentAssemblyTriple);

                    Logger.Information("");
                    Logger.Information("--- Recommended redirect ---\n{Element}", element);

                    if (highestVersionLoaded < highestVersion)
                    {
                        Logger.Warning("WARNING: Recommending a downgrading redirect.");
                    }

                    dependentAssemblyTriples.Add(dependentAssemblyTriple);
                }

                if (dependenciesGrouped.Count > 1)
                {
                    Logger.Information(Separator);
                    Logger.Information("Collected binding redirects:");
                    var element = GetAssemblyBindingXElement(dependentAssemblyTriples.ToArray());
                    Logger.Information("\n{Element}", element);
                }
            }
            else
            {
                Logger.Information(Separator);
                Logger.Information("No recommended binding redirects.");
            }
        }