U4-3425 - TypeHelper referenced assemblies issue
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -66,5 +68,31 @@ namespace Umbraco.Core
|
||||
return new FileInfo(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="AssemblyName"/> objects for all the assemblies recursively referenced by a specified assembly.
|
||||
/// </summary>
|
||||
/// <param name="assembly">The assembly.</param>
|
||||
/// <returns>The <see cref="AssemblyName"/> objects for all the assemblies recursively referenced by the specified assembly.</returns>
|
||||
public static IEnumerable<AssemblyName> GetDeepReferencedAssemblies(this Assembly assembly)
|
||||
{
|
||||
var allAssemblies = TypeFinder.GetAllAssemblies();
|
||||
var visiting = new Stack<Assembly>();
|
||||
var visited = new HashSet<Assembly>();
|
||||
|
||||
visiting.Push(assembly);
|
||||
visited.Add(assembly);
|
||||
while (visiting.Count > 0)
|
||||
{
|
||||
var visAsm = visiting.Pop();
|
||||
foreach (var refAsm in visAsm.GetReferencedAssemblies()
|
||||
.Select(refAsmName => allAssemblies.SingleOrDefault(x => string.Equals(x.GetName().Name, refAsmName.Name, StringComparison.Ordinal)))
|
||||
.Where(x => x != null && visited.Contains(x) == false))
|
||||
{
|
||||
yield return refAsm.GetName();
|
||||
visiting.Push(refAsm);
|
||||
visited.Add(refAsm);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -62,8 +63,17 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
private static bool HasReferenceToAssemblyWithName(Assembly assembly, string expectedAssemblyName)
|
||||
{
|
||||
// The following code was not recursive ie if assembly.1 -> assembly.2 -> assembly.3, and expected is assembly.3,
|
||||
// it would not consider that assembly.1 has a reference to assembly.3. Can cause issues eg when assembly.3
|
||||
// contains an attribute, assembly.2 defines a new attribute that inherit from that attribute, and assembly.1
|
||||
// uses the attribute in assembly.2. When looking for assemblies that have a chance to use the attribute, we
|
||||
// look for assemblies that reference assembly.3, and we would fail to consider assembly.1.
|
||||
//
|
||||
// Better get deep-referenced assemblies. Has an impact on perfs obviously but only when the app starts.
|
||||
|
||||
return assembly
|
||||
.GetReferencedAssemblies()
|
||||
//.GetReferencedAssemblies()
|
||||
.GetDeepReferencedAssemblies()
|
||||
.Select(a => a.Name)
|
||||
.Contains(expectedAssemblyName, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user