private static Assembly AssemblyResolveEventHandler(object sender, ResolveEventArgs args) { // If the assembly that caused this callback is not one of the assemblies packaged with this library, we do nothing: if (args == null || args.Name == null) { return(null); } PackagedAssemblyLookup packagedAssemblies = GetPackagedAssemblies(); if (false == packagedAssemblies.TryFind(args.Name, out PackagedAssemblyLookup.Entry packagedAssemblyInfo)) { return(null); } // Ok, we need to do stuff. // If we already marked this assembly as processed, we are in a recursive call caused by the load request below. // That means load failed even after copy and there is nothing else we can do. if (packagedAssemblyInfo.IsProcessedFromPackage) { Log.Error(LogComonentMoniker, $"The assembly \"{args.Name}\" was not found using the normal assembly resolution method." + $" A fallback assembly binary is included in file \"{packagedAssemblyInfo.AssemblyFilePath}\"." + $" Copying that file into this application's base directory was attempted, but the assembly still cannot be resolved." + $" Giving up."); return(null); } Log.Info(LogComonentMoniker, $"The assembly \"{args.Name}\" was not found using the normal assembly resolution method." + $" A fallback assembly binary is included in file \"{packagedAssemblyInfo.AssemblyFilePath}\"." + $" That file will be now copied into this application's base directory and the loading will be retried."); // Validate AppDomain parameter: Validate.NotNull(sender, nameof(sender)); AppDomain senderAppDomain = sender as AppDomain; if (senderAppDomain == null) { throw new ArgumentException($"The specified {nameof(sender)} is expected to be of runtime type {nameof(AppDomain)}," + $" but the actual type is {sender.GetType().FullName}."); } CopyFileToBaseDirectory(packagedAssemblyInfo.AssemblyFilePath, senderAppDomain); packagedAssemblyInfo.IsProcessedFromPackage = true; Log.Info(LogComonentMoniker, $"Assembly binary copied into this application's base directory. Requesting to load assembly \"{packagedAssemblyInfo.AssemblyName}\"."); #if NETCOREAPP Assembly resolvedAssembly = AssemblyLoadContext.Default.LoadFromAssemblyName(packagedAssemblyInfo.AssemblyName); #else Assembly resolvedAssembly = Assembly.Load(packagedAssemblyInfo.AssemblyName); #endif return(resolvedAssembly); }
private static PackagedAssemblyLookup GetPackagedAssemblies() { PackagedAssemblyLookup packagedAssemblies = s_packagedAssemblies; if (packagedAssemblies == null) { packagedAssemblies = ReadPackagedAssembliesFromDisk(); packagedAssemblies = Concurrent.TrySetOrGetValue(ref s_packagedAssemblies, packagedAssemblies); } return(packagedAssemblies); }
private static PackagedAssemblyLookup ReadPackagedAssembliesFromDisk() { string packagedAssembliesDirectory = GetPackagedAssembliesDirectory(); var packagedAssemblies = new PackagedAssemblyLookup(); if (!Directory.Exists(packagedAssembliesDirectory)) { Log.Error(LogComonentMoniker, $"Could not read any packaged assemblies from disk becasue the directory \"{packagedAssembliesDirectory}\" does not exist."); return(packagedAssemblies); } foreach (string packagedFilePath in Directory.GetFiles(packagedAssembliesDirectory, "*.dll", SearchOption.AllDirectories)) { if (TryGetAssemblyName(packagedFilePath, out AssemblyName assemblyName)) { var packagedAssembly = new PackagedAssemblyLookup.Entry(assemblyName, packagedFilePath); packagedAssemblies.Add(packagedAssembly); } } Log.Info(LogComonentMoniker, $"Read {packagedAssemblies.Count} packaged assemblies from \"{packagedAssembliesDirectory}\"."); return(packagedAssemblies); }