summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs
index 708f79b64f..79f06f30e3 100644
--- a/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs
+++ b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs
@@ -15,11 +15,74 @@ namespace System.Reflection
{
public abstract partial class Assembly : ICustomAttributeProvider, ISerializable
{
+ private static volatile bool s_LoadFromResolveHandlerSetup = false;
+ private static object s_syncRootLoadFrom = new object();
+ private static List<string> s_LoadFromAssemblyList = new List<string>();
+ private static object s_syncLoadFromAssemblyList = new object();
+
+ private static Assembly LoadFromResolveHandler(object sender, ResolveEventArgs args)
+ {
+ Assembly requestingAssembly = args.RequestingAssembly;
+
+ // Requesting assembly for LoadFrom is always loaded in defaultContext - proceed only if that
+ // is the case.
+ if (AssemblyLoadContext.Default != AssemblyLoadContext.GetLoadContext(requestingAssembly))
+ return null;
+
+ // Get the path where requesting assembly lives and check if it is in the list
+ // of assemblies for which LoadFrom was invoked.
+ bool fRequestorLoadedViaLoadFrom = false;
+ string requestorPath = Path.GetFullPath(requestingAssembly.Location);
+ if (string.IsNullOrEmpty(requestorPath))
+ return null;
+
+ lock(s_syncLoadFromAssemblyList)
+ {
+ fRequestorLoadedViaLoadFrom = s_LoadFromAssemblyList.Contains(requestorPath);
+ }
+
+ // If the requestor assembly was not loaded using LoadFrom, exit.
+ if (!fRequestorLoadedViaLoadFrom)
+ return null;
+
+ // Requestor assembly was loaded using loadFrom, so look for its dependencies
+ // in the same folder as it.
+ // Form the name of the assembly using the path of the assembly that requested its load.
+ AssemblyName requestedAssemblyName = new AssemblyName(args.Name);
+ string requestedAssemblyPath = Path.Combine(Path.GetDirectoryName(requestorPath), requestedAssemblyName.Name+".dll");
+
+ return AssemblyLoadContext.Default.LoadFromAssemblyPath(requestedAssemblyPath);
+ }
+
public static Assembly LoadFrom(String assemblyFile)
{
if (assemblyFile == null)
throw new ArgumentNullException(nameof(assemblyFile));
+
string fullPath = Path.GetFullPath(assemblyFile);
+
+ if (!s_LoadFromResolveHandlerSetup)
+ {
+ lock (s_syncRootLoadFrom)
+ {
+ if (!s_LoadFromResolveHandlerSetup)
+ {
+ AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(LoadFromResolveHandler);
+ s_LoadFromResolveHandlerSetup = true;
+ }
+ }
+ }
+
+ // Add the path to the LoadFrom path list which we will consult
+ // before handling the resolves in our handler.
+ lock(s_syncLoadFromAssemblyList)
+ {
+ if (!s_LoadFromAssemblyList.Contains(fullPath))
+ {
+ s_LoadFromAssemblyList.Add(fullPath);
+ }
+ }
+
return AssemblyLoadContext.Default.LoadFromAssemblyPath(fullPath);
}