_cs/CoreAssemblyResolver.cs
using System;
using System.Collections.Generic; using System.Reflection; using System.Runtime.Loader; namespace TfsCmdlets { public class AssemblyResolver { private static bool IsVerbose {get;set;} public static Dictionary<string, string> PrivateAssemblies {get;set;} public static readonly Dictionary<string, Assembly> LoadedAssemblies = new Dictionary<string, Assembly>(); public static readonly Dictionary<string, object> LogEntries = new Dictionary<string, object>(); public static void Register(Dictionary<string, string> privateAssemblies, bool verbose = false) { PrivateAssemblies = privateAssemblies; IsVerbose = verbose; AssemblyLoadContext.Default.Resolving += delegate(AssemblyLoadContext ctx, AssemblyName asmName) { var assemblyName = asmName.FullName.Split(',')[0]; try { if (!PrivateAssemblies.ContainsKey(assemblyName)) { LogWarn("Skipping unknown assembly " + asmName.Name); return null; } var asm = LoadAssembly(assemblyName, ctx); LogInfo(assemblyName + " resolved as '" + asm.FullName + "'"); return asm; } catch(Exception ex) { LogError(ex, assemblyName); return null; } }; } private static Assembly LoadAssembly(string assemblyName, AssemblyLoadContext ctx) { if(LoadedAssemblies.ContainsKey(assemblyName)) { return LoadedAssemblies[assemblyName]; } var assembly = ctx.LoadFromAssemblyName(new AssemblyName(PrivateAssemblies[assemblyName])); LoadedAssemblies.Add(assemblyName, assembly); return assembly; } private static void Log(string message, object data) { message = "[" + (LogEntries.Count+1).ToString("00000") + " - " + DateTime.Now.ToString("HH:mm:ss.ffff") + "] " + message; LogEntries.Add(message, data); } private static void LogInfo(string message) { if (!IsVerbose) return; Log("[INFO ] " + message, string.Empty); } private static void LogWarn(string message) { Log("[WARN ] " + message, string.Empty); } private static void LogError(Exception ex, string assemblyName = null) { Log("[ERROR] Loading assembly " + (assemblyName?? "(unknown)"), ex); } } } |