Tweak IAssemblyLoader loadig policy

A few common .net framework assemblies are referenced by the Orchard.Framework
assembly. Look into those to see if we can find the assembly we are looking for.

This is useful for orchard modules project files, where commonly used assemblies
don't need to be specified with a strong name.

--HG--
branch : dev
This commit is contained in:
Renaud Paquay
2010-11-21 21:59:24 -08:00
parent e0d24527b1
commit e4ba511525
3 changed files with 29 additions and 10 deletions

View File

@@ -11,7 +11,7 @@ namespace Orchard.Tests.FileSystems.Dependencies {
public void FolderShouldBeEmptyByDefault() {
var clock = new StubClock();
var appDataFolder = new StubAppDataFolder(clock);
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader());
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader(new StubCacheManager()));
Assert.That(dependenciesFolder.AssemblyExists("foo"), Is.False);
}
@@ -20,7 +20,7 @@ namespace Orchard.Tests.FileSystems.Dependencies {
public void LoadAssemblyShouldNotThrowIfAssemblyNotFound() {
var clock = new StubClock();
var appDataFolder = new StubAppDataFolder(clock);
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader());
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader(new StubCacheManager()));
Assert.That(dependenciesFolder.LoadAssembly("foo"), Is.Null);
}
@@ -29,7 +29,7 @@ namespace Orchard.Tests.FileSystems.Dependencies {
public void GetAssemblyDateTimeUtcShouldThrowIfAssemblyNotFound() {
var clock = new StubClock();
var appDataFolder = new StubAppDataFolder(clock);
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader());
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader(new StubCacheManager()));
Assert.That(() => dependenciesFolder.GetAssemblyDateTimeUtc("foo"), Throws.Exception);
}
@@ -38,7 +38,7 @@ namespace Orchard.Tests.FileSystems.Dependencies {
public void DeleteAssemblyShouldNotThrowIfAssemblyNotFound() {
var clock = new StubClock();
var appDataFolder = new StubAppDataFolder(clock);
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader());
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader(new StubCacheManager()));
Assert.DoesNotThrow(() => dependenciesFolder.DeleteAssembly("foo"));
}
@@ -52,12 +52,12 @@ namespace Orchard.Tests.FileSystems.Dependencies {
var name = assembly.GetName().Name;
{
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader());
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader(new StubCacheManager()));
dependenciesFolder.StoreAssembly(name, assembly.Location);
}
{
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader());
var dependenciesFolder = new DefaultAssemblyProbingFolder(appDataFolder, new DefaultAssemblyLoader(new StubCacheManager()));
Assert.That(dependenciesFolder.AssemblyExists(name), Is.True);
Assert.That(dependenciesFolder.LoadAssembly(name), Is.SameAs(GetType().Assembly));
Assert.DoesNotThrow(() => dependenciesFolder.DeleteAssembly(name));

View File

@@ -45,7 +45,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll</HintPath>

View File

@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Orchard.Caching;
using Orchard.Logging;
namespace Orchard.Environment {
@@ -11,9 +12,11 @@ namespace Orchard.Environment {
}
public class DefaultAssemblyLoader : IAssemblyLoader {
private readonly ICacheManager _cacheManager;
private readonly ConcurrentDictionary<string, Assembly> _loadedAssemblies = new ConcurrentDictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
public DefaultAssemblyLoader() {
public DefaultAssemblyLoader(ICacheManager cacheManager) {
_cacheManager = cacheManager;
Logger = NullLogger.Instance;
}
@@ -28,16 +31,32 @@ namespace Orchard.Environment {
return null;
}
}
private Assembly LoadWorker(string shortName, string fullName) {
// If short assembly name, look in list of loaded assemblies first
// If short assembly name, try to figure out the full assembly name using
// a policy compatible with Medium Trust.
if (shortName == fullName) {
// Look in assemblies loaded in the AppDomain first.
var result = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => StringComparer.OrdinalIgnoreCase.Equals(shortName, this.ExtractAssemblyName(a.FullName)))
.SingleOrDefault();
if (result != null)
return result;
// A few common .net framework assemblies are referenced by the Orchard.Framework assembly.
// Look into those to see if we can find the assembly we are looking for.
var orchardFrameworkReferences = _cacheManager.Get(
typeof(IAssemblyLoader),
ctx => ctx.Key.Assembly
.GetReferencedAssemblies()
.GroupBy(n => this.ExtractAssemblyName(n.FullName), StringComparer.OrdinalIgnoreCase)
.ToDictionary(n => n.Key /*short assembly name*/, g => g.OrderBy(n => n.Version).Last() /* highest assembly version */, StringComparer.OrdinalIgnoreCase));
AssemblyName assemblyName;
if (orchardFrameworkReferences.TryGetValue(shortName, out assemblyName)) {
return Assembly.Load(assemblyName.FullName);
}
}
return Assembly.Load(fullName);