diff --git a/src/Orchard.Web/Web.config b/src/Orchard.Web/Web.config index c337ae4ce..e89891961 100644 --- a/src/Orchard.Web/Web.config +++ b/src/Orchard.Web/Web.config @@ -63,8 +63,6 @@ - - diff --git a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs index ad1c42f8b..298e9d5b3 100644 --- a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs +++ b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs @@ -247,7 +247,20 @@ namespace Orchard.Environment.Extensions { } private IEnumerable SortExtensionProbeEntries(IEnumerable entries, ConcurrentDictionary virtualPathModficationDates) { - return entries + // All "entries" are for the same extension ID, so we just need to filter/sort them by priority+ modification dates. + var groupByPriority = entries + .GroupBy(entry => entry.Priority) + .OrderByDescending(g => g.Key); + + // Select highest priority group with at least one item + var firstNonEmptyGroup = groupByPriority.FirstOrDefault(g => g.Count() >= 1) ?? Enumerable.Empty(); + + // No need for further sorting if only 1 item found + if (firstNonEmptyGroup.Count() <= 1) + return firstNonEmptyGroup; + + // Sort by last modification date/loader order + return firstNonEmptyGroup .OrderByDescending(probe => GetVirtualPathDepedenciesModificationTimeUtc(virtualPathModficationDates, probe)) .ThenBy(probe => probe.Loader.Order) .ToList(); diff --git a/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs index 9e6621ddb..f30b9b351 100644 --- a/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs @@ -32,6 +32,7 @@ namespace Orchard.Environment.Extensions.Loaders { return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this, + Priority = 100, // Higher priority because assemblies in ~/bin always take precedence VirtualPath = "~/Core/" + descriptor.Id, VirtualPathDependencies = Enumerable.Empty(), }; diff --git a/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs index eb904148a..d3890d616 100644 --- a/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs @@ -9,6 +9,7 @@ namespace Orchard.Environment.Extensions.Loaders { public class ExtensionProbeEntry { public ExtensionDescriptor Descriptor { get; set; } public IExtensionLoader Loader { get; set; } + public int Priority { get; set; } public string VirtualPath { get; set; } public IEnumerable VirtualPathDependencies { get; set; } } diff --git a/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs index 9bee57fd7..c3d4581b1 100644 --- a/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Collections.Generic; +using System.IO; using System.Linq; using Orchard.Environment.Extensions.Models; using Orchard.FileSystems.Dependencies; @@ -59,6 +60,7 @@ namespace Orchard.Environment.Extensions.Loaders { return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this, + Priority = 100, // Higher priority because assemblies in ~/bin always take precedence VirtualPath = assemblyPath, VirtualPathDependencies = new[] { assemblyPath }, }; diff --git a/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs b/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs index 082bc3c84..12505b9db 100644 --- a/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs +++ b/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs @@ -113,7 +113,12 @@ namespace Orchard.HostContext { } private static CommandHost CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType) { - ClientBuildManager clientBuildManager = new ClientBuildManager(virtualPath, physicalPath); + var clientBuildManager = new ClientBuildManager(virtualPath, physicalPath); + // Fix for http://orchard.codeplex.com/workitem/17920 + // By forcing the CBM to build App_Code, etc, we ensure that the ASP.NET BuildManager + // is in a state where it can safely (i.e. in a multi-threaded safe way) process + // multiple concurrent calls to "GetCompiledAssembly". + clientBuildManager.CompileApplicationDependencies(); return (CommandHost)clientBuildManager.CreateObject(hostType, false); } }