summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPawel Andruszkiewicz <p.andruszkie@samsung.com>2016-12-09 08:52:45 +0100
committerJongHeon Choi <j-h.choi@samsung.com>2016-12-19 21:03:09 +0900
commit095697508a12bc9c471e096fdbd0a2e2b0b8f458 (patch)
tree2d7d98a012f2e07db30be1283657e9b7bc2458bb
parentfc168cf98012b338709f2a80bf11fe24d34f6903 (diff)
downloadlauncher-095697508a12bc9c471e096fdbd0a2e2b0b8f458.tar.gz
launcher-095697508a12bc9c471e096fdbd0a2e2b0b8f458.tar.bz2
launcher-095697508a12bc9c471e096fdbd0a2e2b0b8f458.zip
AssemblyLoader should assist in loading all assemblies
The Resolving event from the AssemblyLoadContext is invoked each time it fails to load an assembly. The default AssemblyLoadContext is used internally i.e. when Assembly.Load() or Type.GetType(string) methods are called. Registering for the Resolving event from the default AssemblyLoadContext helps handling the unresolved assemblies and fixes XAML-related issues in Xamarin. TASK=TNET-136 TASK=TCAPI-1863 Change-Id: I0f5f4c2925829eac448a6184a3e19dbde5c1dfc0 Signed-off-by: Pawel Andruszkiewicz <p.andruszkie@samsung.com>
-rwxr-xr-xTizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs89
-rw-r--r--Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs24
2 files changed, 69 insertions, 44 deletions
diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs
index cbb0095..35a8ddf 100755
--- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs
+++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs
@@ -16,6 +16,7 @@
using System;
using System.IO;
+using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Collections.Generic;
@@ -24,9 +25,24 @@ namespace Tizen.Runtime.Coreclr
{
public class AssemblyLoader : AssemblyLoadContext
{
+ private const string NativeAssemblyInfix = ".ni";
+
+ private const string DllAssemblySuffix = ".dll";
+
+ private const string NativeDllAssemblySuffix = NativeAssemblyInfix + DllAssemblySuffix;
+
+ private static readonly string[] s_suffixes = new string[] { NativeDllAssemblySuffix, DllAssemblySuffix };
+
private SortedSet<string> _dllDirectories = new SortedSet<string>();
private SortedSet<string> _nativeDirectories = new SortedSet<string>();
+ private HashSet<FileInfo> _dllCache = new HashSet<FileInfo>();
+
+ public AssemblyLoader()
+ {
+ AssemblyLoadContext.Default.Resolving += OnResolving;
+ }
+
public IEnumerable<string> DllDirectories
{
get { return _dllDirectories; }
@@ -43,6 +59,16 @@ namespace Tizen.Runtime.Coreclr
{
_dllDirectories.Add(directory);
_nativeDirectories.Add(directory);
+
+ foreach (var file in Directory.GetFiles(directory))
+ {
+ var info = new FileInfo(file);
+
+ if (info.Extension == DllAssemblySuffix)
+ {
+ _dllCache.Add(info);
+ }
+ }
}
}
@@ -50,39 +76,30 @@ namespace Tizen.Runtime.Coreclr
{
_dllDirectories.Remove(directory);
_nativeDirectories.Remove(directory);
+
+ _dllCache.RemoveWhere(x => x.DirectoryName == directory);
}
- protected override Assembly Load(AssemblyName assemblyName)
+ public Assembly LoadFromPath(string path)
{
- Assembly asm = null;
-
- try
+ if (0 == string.Compare(path, // strA
+ path.Length - NativeDllAssemblySuffix.Length, // indexA
+ NativeAssemblyInfix, // strB
+ 0, // indexB
+ NativeAssemblyInfix.Length, // length
+ StringComparison.OrdinalIgnoreCase)) // options
{
- //asm = AssemblyLoadContext.Default.Load(assemblyName);
- asm = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName);
+ return LoadFromNativeImagePath(path, null);
}
- catch (Exception ex)
- when (ex is FileNotFoundException ||
- ex is BadImageFormatException ||
- ex is FileLoadException)
+ else
{
- foreach (string dir in DllDirectories)
- {
- FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.ni.dll"));
- if (File.Exists(f.FullName))
- {
- asm = LoadFromNativeImagePath(f.FullName, null);
- break;
- }
- f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll"));
- if (File.Exists(f.FullName))
- {
- asm = LoadFromAssemblyPath(f.FullName);
- break;
- }
- }
+ return LoadFromAssemblyPath(path);
}
- return asm;
+ }
+
+ protected override Assembly Load(AssemblyName assemblyName)
+ {
+ return Resolve(assemblyName);
}
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
@@ -103,5 +120,25 @@ namespace Tizen.Runtime.Coreclr
return native;
}
+
+ private Assembly Resolve(AssemblyName assemblyName)
+ {
+ foreach (string suffix in s_suffixes)
+ {
+ var info = _dllCache.FirstOrDefault(x => x.Name == assemblyName.Name + suffix);
+
+ if (info != null)
+ {
+ return LoadFromPath(info.FullName);
+ }
+ }
+
+ return null;
+ }
+
+ private Assembly OnResolving(AssemblyLoadContext context, AssemblyName assemblyName)
+ {
+ return Resolve(assemblyName);
+ }
}
}
diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs
index 52297a1..de0b293 100644
--- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs
+++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs
@@ -146,15 +146,7 @@ namespace Tizen.Runtime.Coreclr
ALog.Debug($"preload dll : {s}");
try
{
- Assembly asm = null;
- if (s.EndsWith(".ni.dll", StringComparison.CurrentCultureIgnoreCase))
- {
- asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(s, null);
- }
- else
- {
- asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(s);
- }
+ Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(s);
// this works strange, vm can't load types except loaded in here.
// so user code spit out not found exception.
@@ -195,20 +187,16 @@ namespace Tizen.Runtime.Coreclr
FileInfo f = new FileInfo(dllPath);
if (File.Exists(f.FullName))
{
- Assembly asm = null;
- if (0 == string.Compare(f.FullName, f.FullName.Length - 7, ".ni", 0, 3, StringComparison.OrdinalIgnoreCase))
- {
- asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(f.FullName, null);
- }
- else
- {
- asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(f.FullName);
- }
+ Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(f.FullName);
if (asm == null) throw new FileNotFoundException($"{f.FullName} is not found");
if (asm.EntryPoint == null) throw new ArgumentException($"{f.FullName} did not have EntryPoint");
asm.EntryPoint.Invoke(null, new object[]{argv});
}
+ else
+ {
+ ALog.Debug($"Requested file does not exist: {dllPath}");
+ }
}
catch (Exception e)
{