From f4a9b0c63c4688e680d213ab78fdf35718c43fe7 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Wed, 10 Nov 2010 15:03:51 -0800 Subject: [PATCH] Fix assembly loader to check for assemblies in AppDomain Also update the csproj build provider and parse to use full assembly name if they are present --HG-- branch : perf --- .../Compilers/DefaultExtensionCompiler.cs | 17 ++++------- .../Compilers/DefaultProjectFileParser.cs | 4 +-- .../Compilers/ProjectFileDescriptor.cs | 3 +- .../Loaders/DynamicExtensionLoader.cs | 4 +-- src/Orchard/Environment/IAssemblyLoader.cs | 30 ++++++++++++++++++- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs b/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs index 75d499fb4..02105875e 100644 --- a/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs +++ b/src/Orchard/Environment/Extensions/Compilers/DefaultExtensionCompiler.cs @@ -59,7 +59,6 @@ namespace Orchard.Environment.Extensions.Compilers { } // Add assembly references - var addedReferences = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var reference in dependencyDescriptor.References) { var referenceTemp = reference; var loader = _loaders.SingleOrDefault(l => l.Name == referenceTemp.LoaderName); @@ -67,22 +66,18 @@ namespace Orchard.Environment.Extensions.Compilers { var assembly = loader.LoadReference(reference); if (assembly != null) { context.AssemblyBuilder.AddAssemblyReference(assembly); - addedReferences.Add(reference.Name); } } } // Load references specified in project file foreach (var assemblyReference in descriptor.References) { - if (!addedReferences.Contains(assemblyReference.AssemblyName)) { - var assembly = _assemblyLoader.Load(assemblyReference.AssemblyName); - if (assembly != null) { - context.AssemblyBuilder.AddAssemblyReference(assembly); - addedReferences.Add(assemblyReference.AssemblyName); - } - else { - Logger.Warning("Assembly reference '{0}' for project '{1}' skipped due to load error", assemblyReference.AssemblyName, context.VirtualPath); - } + var assembly = _assemblyLoader.Load(assemblyReference.FullName); + if (assembly != null) { + context.AssemblyBuilder.AddAssemblyReference(assembly); + } + else { + Logger.Warning("Assembly reference '{0}' for project '{1}' skipped due to load error", assemblyReference.FullName, context.VirtualPath); } } } diff --git a/src/Orchard/Environment/Extensions/Compilers/DefaultProjectFileParser.cs b/src/Orchard/Environment/Extensions/Compilers/DefaultProjectFileParser.cs index d9e8c9aa2..53ab98ea3 100644 --- a/src/Orchard/Environment/Extensions/Compilers/DefaultProjectFileParser.cs +++ b/src/Orchard/Environment/Extensions/Compilers/DefaultProjectFileParser.cs @@ -40,14 +40,14 @@ namespace Orchard.Environment.Extensions.Compilers { .Elements(ns("ItemGroup")) .Elements(ns("Reference")) .Attributes("Include") - .Select(c => new ReferenceDescriptor { AssemblyName = ExtractAssemblyName(c.Value) }); + .Select(c => new ReferenceDescriptor { SimpleName = ExtractAssemblyName(c.Value), FullName = c.Value }); var projectReferences = document .Elements(ns("Project")) .Elements(ns("ItemGroup")) .Elements(ns("ProjectReference")) .Attributes("Include") - .Select(c => new ReferenceDescriptor { AssemblyName = Path.GetFileNameWithoutExtension(c.Value) }); + .Select(c => new ReferenceDescriptor { SimpleName = Path.GetFileNameWithoutExtension(c.Value), FullName = Path.GetFileNameWithoutExtension(c.Value) }); return assemblyReferences.Union(projectReferences); } diff --git a/src/Orchard/Environment/Extensions/Compilers/ProjectFileDescriptor.cs b/src/Orchard/Environment/Extensions/Compilers/ProjectFileDescriptor.cs index 7fef8e138..a4387f117 100644 --- a/src/Orchard/Environment/Extensions/Compilers/ProjectFileDescriptor.cs +++ b/src/Orchard/Environment/Extensions/Compilers/ProjectFileDescriptor.cs @@ -7,6 +7,7 @@ namespace Orchard.Environment.Extensions.Compilers { public IEnumerable References { get; set; } } public class ReferenceDescriptor { - public string AssemblyName { get; set; } + public string SimpleName { get; set; } + public string FullName { get; set; } } } \ No newline at end of file diff --git a/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs index f788fd7e0..a186021b5 100644 --- a/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/DynamicExtensionLoader.cs @@ -109,8 +109,8 @@ namespace Orchard.Environment.Extensions.Loaders { return projectFile.References.Select(r => new ExtensionReferenceProbeEntry { Descriptor = descriptor, Loader = this, - Name = r.AssemblyName, - VirtualPath = GetReferenceVirtualPath(projectPath, r.AssemblyName) + Name = r.SimpleName, + VirtualPath = GetReferenceVirtualPath(projectPath, r.SimpleName) }); } } diff --git a/src/Orchard/Environment/IAssemblyLoader.cs b/src/Orchard/Environment/IAssemblyLoader.cs index 004d45ac3..974f4d810 100644 --- a/src/Orchard/Environment/IAssemblyLoader.cs +++ b/src/Orchard/Environment/IAssemblyLoader.cs @@ -1,4 +1,7 @@ using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; using System.Reflection; using Orchard.Logging; @@ -8,6 +11,8 @@ namespace Orchard.Environment { } public class DefaultAssemblyLoader : IAssemblyLoader { + private readonly ConcurrentDictionary _loadedAssemblies = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + public DefaultAssemblyLoader() { Logger = NullLogger.Instance; } @@ -16,12 +21,35 @@ namespace Orchard.Environment { public Assembly Load(string assemblyName) { try { - return Assembly.Load(assemblyName); + return _loadedAssemblies.GetOrAdd(this.ExtractAssemblyName(assemblyName), shortName => LoadWorker(shortName, assemblyName)); } catch (Exception e) { Logger.Warning(e, "Error loading assembly '{0}'", assemblyName); return null; } } + + private Assembly LoadWorker(string shortName, string fullName) { + // If short assembly name, look in list of loaded assemblies first + if (shortName == fullName) { + var result = AppDomain.CurrentDomain.GetAssemblies() + .Where(a => StringComparer.OrdinalIgnoreCase.Equals(shortName, a.GetName().Name)) + .SingleOrDefault(); + + if (result != null) + return result; + } + + return Assembly.Load(fullName); + } + } + + public static class AssemblyLoaderExtensions { + public static string ExtractAssemblyName(this IAssemblyLoader assemblyLoader, string fullName) { + int index = fullName.IndexOf(','); + if (index < 0) + return fullName; + return fullName.Substring(0, index); + } } }