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";
29 private const string DllAssemblySuffix = ".dll";
30 private const string ExeAssemblySuffix = ".exe";
31 private const string NativeDllAssemblySuffix = NativeAssemblyInfix + DllAssemblySuffix;
32 private static readonly string[] Suffixes = new string[] { NativeDllAssemblySuffix, DllAssemblySuffix, ExeAssemblySuffix };
33 private SortedSet<string> DllDirectoriesSet = new SortedSet<string>();
34 private SortedSet<string> NativeDirectoriesSet = new SortedSet<string>();
35 private HashSet<FileInfo> AssemblyCacheSet = new HashSet<FileInfo>();
37 public AssemblyLoader()
39 AssemblyLoadContext.Default.Resolving += OnResolving;
42 public IEnumerable<string> DllDirectories
44 get { return DllDirectoriesSet; }
47 public IEnumerable<string> NativeDirectories
49 get { return NativeDirectoriesSet; }
52 public void AddSearchableDirectory(string directory)
54 if (Directory.Exists(directory))
56 DllDirectoriesSet.Add(directory);
57 NativeDirectoriesSet.Add(directory);
59 foreach (var file in Directory.GetFiles(directory))
61 var info = new FileInfo(file);
63 if (Suffixes.Contains(info.Extension))
65 AssemblyCacheSet.Add(info);
71 public void RemoveSearchableDirectory(string directory)
73 DllDirectoriesSet.Remove(directory);
74 NativeDirectoriesSet.Remove(directory);
76 AssemblyCacheSet.RemoveWhere(x => x.DirectoryName == directory);
79 public Assembly LoadFromPath(string path)
81 if (string.Compare(path, path.Length - NativeDllAssemblySuffix.Length, NativeAssemblyInfix, 0, NativeAssemblyInfix.Length, StringComparison.OrdinalIgnoreCase) == 0)
83 return LoadFromNativeImagePath(path, null);
87 return LoadFromAssemblyPath(path);
91 protected override Assembly Load(AssemblyName assemblyName)
93 return Resolve(assemblyName);
96 protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
98 IntPtr native = base.LoadUnmanagedDll(unmanagedDllName);
99 if (native == IntPtr.Zero)
101 foreach (string dir in NativeDirectories)
103 FileInfo f = new FileInfo(Path.Combine(dir, unmanagedDllName));
104 if (File.Exists(f.FullName))
106 native = LoadUnmanagedDllFromPath(f.FullName);
115 private Assembly Resolve(AssemblyName assemblyName)
117 foreach (string suffix in Suffixes)
119 var info = AssemblyCacheSet.FirstOrDefault(x => x.Name == assemblyName.Name + suffix);
123 return LoadFromPath(info.FullName);
130 private Assembly OnResolving(AssemblyLoadContext context, AssemblyName assemblyName)
132 return Resolve(assemblyName);