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
This commit is contained in:
Renaud Paquay
2010-11-10 15:03:51 -08:00
parent a284f16056
commit f4a9b0c63c
5 changed files with 41 additions and 17 deletions

View File

@@ -59,7 +59,6 @@ namespace Orchard.Environment.Extensions.Compilers {
} }
// Add assembly references // Add assembly references
var addedReferences = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (var reference in dependencyDescriptor.References) { foreach (var reference in dependencyDescriptor.References) {
var referenceTemp = reference; var referenceTemp = reference;
var loader = _loaders.SingleOrDefault(l => l.Name == referenceTemp.LoaderName); var loader = _loaders.SingleOrDefault(l => l.Name == referenceTemp.LoaderName);
@@ -67,22 +66,18 @@ namespace Orchard.Environment.Extensions.Compilers {
var assembly = loader.LoadReference(reference); var assembly = loader.LoadReference(reference);
if (assembly != null) { if (assembly != null) {
context.AssemblyBuilder.AddAssemblyReference(assembly); context.AssemblyBuilder.AddAssemblyReference(assembly);
addedReferences.Add(reference.Name);
} }
} }
} }
// Load references specified in project file // Load references specified in project file
foreach (var assemblyReference in descriptor.References) { foreach (var assemblyReference in descriptor.References) {
if (!addedReferences.Contains(assemblyReference.AssemblyName)) { var assembly = _assemblyLoader.Load(assemblyReference.FullName);
var assembly = _assemblyLoader.Load(assemblyReference.AssemblyName); if (assembly != null) {
if (assembly != null) { context.AssemblyBuilder.AddAssemblyReference(assembly);
context.AssemblyBuilder.AddAssemblyReference(assembly); }
addedReferences.Add(assemblyReference.AssemblyName); else {
} Logger.Warning("Assembly reference '{0}' for project '{1}' skipped due to load error", assemblyReference.FullName, context.VirtualPath);
else {
Logger.Warning("Assembly reference '{0}' for project '{1}' skipped due to load error", assemblyReference.AssemblyName, context.VirtualPath);
}
} }
} }
} }

View File

@@ -40,14 +40,14 @@ namespace Orchard.Environment.Extensions.Compilers {
.Elements(ns("ItemGroup")) .Elements(ns("ItemGroup"))
.Elements(ns("Reference")) .Elements(ns("Reference"))
.Attributes("Include") .Attributes("Include")
.Select(c => new ReferenceDescriptor { AssemblyName = ExtractAssemblyName(c.Value) }); .Select(c => new ReferenceDescriptor { SimpleName = ExtractAssemblyName(c.Value), FullName = c.Value });
var projectReferences = document var projectReferences = document
.Elements(ns("Project")) .Elements(ns("Project"))
.Elements(ns("ItemGroup")) .Elements(ns("ItemGroup"))
.Elements(ns("ProjectReference")) .Elements(ns("ProjectReference"))
.Attributes("Include") .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); return assemblyReferences.Union(projectReferences);
} }

View File

@@ -7,6 +7,7 @@ namespace Orchard.Environment.Extensions.Compilers {
public IEnumerable<ReferenceDescriptor> References { get; set; } public IEnumerable<ReferenceDescriptor> References { get; set; }
} }
public class ReferenceDescriptor { public class ReferenceDescriptor {
public string AssemblyName { get; set; } public string SimpleName { get; set; }
public string FullName { get; set; }
} }
} }

View File

@@ -109,8 +109,8 @@ namespace Orchard.Environment.Extensions.Loaders {
return projectFile.References.Select(r => new ExtensionReferenceProbeEntry { return projectFile.References.Select(r => new ExtensionReferenceProbeEntry {
Descriptor = descriptor, Descriptor = descriptor,
Loader = this, Loader = this,
Name = r.AssemblyName, Name = r.SimpleName,
VirtualPath = GetReferenceVirtualPath(projectPath, r.AssemblyName) VirtualPath = GetReferenceVirtualPath(projectPath, r.SimpleName)
}); });
} }
} }

View File

@@ -1,4 +1,7 @@
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection; using System.Reflection;
using Orchard.Logging; using Orchard.Logging;
@@ -8,6 +11,8 @@ namespace Orchard.Environment {
} }
public class DefaultAssemblyLoader : IAssemblyLoader { public class DefaultAssemblyLoader : IAssemblyLoader {
private readonly ConcurrentDictionary<string, Assembly> _loadedAssemblies = new ConcurrentDictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
public DefaultAssemblyLoader() { public DefaultAssemblyLoader() {
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
} }
@@ -16,12 +21,35 @@ namespace Orchard.Environment {
public Assembly Load(string assemblyName) { public Assembly Load(string assemblyName) {
try { try {
return Assembly.Load(assemblyName); return _loadedAssemblies.GetOrAdd(this.ExtractAssemblyName(assemblyName), shortName => LoadWorker(shortName, assemblyName));
} }
catch (Exception e) { catch (Exception e) {
Logger.Warning(e, "Error loading assembly '{0}'", assemblyName); Logger.Warning(e, "Error loading assembly '{0}'", assemblyName);
return null; 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);
}
} }
} }