U4-3425 - TypeHelper referenced assemblies issue

This commit is contained in:
Stephan
2014-04-19 16:44:33 +02:00
parent 3bf1041041
commit 536b8ee921
2 changed files with 39 additions and 1 deletions

View File

@@ -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);
}
}
}
}
}

View File

@@ -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);
}