Last active
February 4, 2016 15:02
-
-
Save khellang/36fdbce2b8c65ea6d8e6 to your computer and use it in GitHub Desktop.
Assembly loading and scanning
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class Program | |
{ | |
private static readonly AssemblyName CurrentAssemblyName = typeof(Program).Assembly.GetName(); | |
public static void Main() | |
{ | |
var mainDomain = AppDomain.CurrentDomain; | |
var assemblyFolders = mainDomain.GetAssemblyFolders(); | |
var assemblyNames = GetAssemblyNames(assemblyFolders); | |
var assembliesToLoad = GetAssembliesToLoad(assemblyNames); | |
var loadedAssemblies = mainDomain.LoadAssemblies(assembliesToLoad); | |
Console.WriteLine("Loaded the following assemblies:"); | |
foreach (var loadedAssembly in loadedAssemblies) | |
{ | |
Console.WriteLine(loadedAssembly); | |
} | |
Console.ReadLine(); | |
} | |
private static IEnumerable<string> GetAssemblyFolders(this AppDomain appDomain) | |
{ | |
var assemblyFolders = new List<string>(); | |
var setupInfo = appDomain.SetupInformation; | |
if (!string.IsNullOrEmpty(setupInfo.PrivateBinPath)) | |
{ | |
var binPaths = setupInfo.PrivateBinPath.Split(';'); | |
foreach (var binPath in binPaths) | |
{ | |
if (!string.IsNullOrEmpty(binPath)) | |
{ | |
assemblyFolders.Add(binPath.Trim()); | |
} | |
} | |
} | |
if (string.IsNullOrEmpty(setupInfo.PrivateBinPath)) | |
{ | |
assemblyFolders.Add(setupInfo.ApplicationBase); | |
} | |
return assemblyFolders.ToArray(); | |
} | |
private static IEnumerable<AssemblyName> GetAssemblyNames(IEnumerable<string> assemblyFolders) | |
{ | |
var assemblyNames = new HashSet<AssemblyName>(); | |
foreach (var assemblyFolder in assemblyFolders) | |
{ | |
var assemblyPaths = Directory.EnumerateFiles(assemblyFolder, "*.dll"); | |
foreach (var assemblyPath in assemblyPaths) | |
{ | |
assemblyNames.Add(AssemblyName.GetAssemblyName(assemblyPath)); | |
} | |
} | |
return assemblyNames.ToArray(); | |
} | |
private static IEnumerable<AssemblyName> GetAssembliesToLoad(IEnumerable<AssemblyName> assemblyNames) | |
{ | |
var assembliesToLoad = new List<AssemblyName>(); | |
var reflectionDomain = AppDomain.CreateDomain("Nancy Reflection Domain"); | |
foreach (var assemblyName in assemblyNames) | |
{ | |
Assembly assembly; | |
if (reflectionDomain.TryLoadAssembly(assemblyName, out assembly)) | |
{ | |
var references = assembly.GetReferencedAssemblies(); | |
foreach (var reference in references) | |
{ | |
if (AssemblyName.ReferenceMatchesDefinition(reference, CurrentAssemblyName)) | |
{ | |
assembliesToLoad.Add(assemblyName); | |
} | |
} | |
} | |
} | |
AppDomain.Unload(reflectionDomain); | |
return assembliesToLoad.ToArray(); | |
} | |
private static IEnumerable<Assembly> LoadAssemblies(this AppDomain appDomain, IEnumerable<AssemblyName> assemblyNames) | |
{ | |
var loadedAssemblies = new List<Assembly>(); | |
foreach (var assemblyName in assemblyNames) | |
{ | |
Assembly assembly; | |
if (appDomain.TryLoadAssembly(assemblyName, out assembly)) | |
{ | |
loadedAssemblies.Add(assembly); | |
} | |
} | |
return loadedAssemblies.ToArray(); | |
} | |
private static bool TryLoadAssembly(this AppDomain appDomain, AssemblyName assemblyName, out Assembly assembly) | |
{ | |
try | |
{ | |
assembly = appDomain.Load(assemblyName); | |
return true; | |
} | |
catch (Exception) | |
{ | |
assembly = null; | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment