2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 using System.Reflection;
21 using System.Runtime.Loader;
22 using System.Collections.Generic;
24 namespace Tizen.Runtime.Coreclr
26 public class AssemblyLoader : AssemblyLoadContext
28 private const string NativeAssemblyInfix = ".ni";
30 private const string DllAssemblySuffix = ".dll";
32 private const string ExeAssemblySuffix = ".exe";
34 private const string NativeDllAssemblySuffix = NativeAssemblyInfix + DllAssemblySuffix;
36 private static readonly string[] s_suffixes = new string[] { NativeDllAssemblySuffix, DllAssemblySuffix, ExeAssemblySuffix };
38 private SortedSet<string> _dllDirectories = new SortedSet<string>();
39 private SortedSet<string> _nativeDirectories = new SortedSet<string>();
41 private HashSet<FileInfo> _assemblyCache = new HashSet<FileInfo>();
43 public AssemblyLoader()
45 AssemblyLoadContext.Default.Resolving += OnResolving;
48 public IEnumerable<string> DllDirectories
50 get { return _dllDirectories; }
53 public IEnumerable<string> NativeDirectories
55 get { return _nativeDirectories; }
58 public void AddSearchableDirectory(string directory)
60 if (Directory.Exists(directory))
62 _dllDirectories.Add(directory);
63 _nativeDirectories.Add(directory);
65 foreach (var file in Directory.GetFiles(directory))
67 var info = new FileInfo(file);
69 if (s_suffixes.Contains(info.Extension))
71 _assemblyCache.Add(info);
77 public void RemoveSearchableDirectory(string directory)
79 _dllDirectories.Remove(directory);
80 _nativeDirectories.Remove(directory);
82 _assemblyCache.RemoveWhere(x => x.DirectoryName == directory);
85 public Assembly LoadFromPath(string path)
87 if (0 == string.Compare(path, // strA
88 path.Length - NativeDllAssemblySuffix.Length, // indexA
89 NativeAssemblyInfix, // strB
91 NativeAssemblyInfix.Length, // length
92 StringComparison.OrdinalIgnoreCase)) // options
94 return LoadFromNativeImagePath(path, null);
98 return LoadFromAssemblyPath(path);
102 protected override Assembly Load(AssemblyName assemblyName)
104 return Resolve(assemblyName);
107 protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
109 IntPtr native = base.LoadUnmanagedDll(unmanagedDllName);
110 if (native == IntPtr.Zero)
112 foreach (string dir in NativeDirectories)
114 FileInfo f = new FileInfo(Path.Combine(dir, unmanagedDllName));
115 if (File.Exists(f.FullName))
117 native = LoadUnmanagedDllFromPath(f.FullName);
126 private Assembly Resolve(AssemblyName assemblyName)
128 foreach (string suffix in s_suffixes)
130 var info = _assemblyCache.FirstOrDefault(x => x.Name == assemblyName.Name + suffix);
134 return LoadFromPath(info.FullName);
141 private Assembly OnResolving(AssemblyLoadContext context, AssemblyName assemblyName)
143 return Resolve(assemblyName);