public AssemblyDependencyResolver(string componentAssemblyPath) { if (componentAssemblyPath == null) { throw new ArgumentNullException(nameof(componentAssemblyPath)); } string?assemblyPathsList = null; string?nativeSearchPathsList = null; string?resourceSearchPathsList = null; int returnCode = 0; StringBuilder errorMessage = new StringBuilder(); try { // Setup error writer for this thread. This makes the hostpolicy redirect all error output // to the writer specified. Have to store the previous writer to set it back once this is done. corehost_error_writer_fn errorWriter = new corehost_error_writer_fn(message => { errorMessage.AppendLine(message); }); IntPtr errorWriterPtr = Marshal.GetFunctionPointerForDelegate(errorWriter); IntPtr previousErrorWriterPtr = corehost_set_error_writer(errorWriterPtr); try { // Call hostpolicy to do the actual work of finding .deps.json, parsing it and extracting // information from it. returnCode = corehost_resolve_component_dependencies( componentAssemblyPath, (assembly_paths, native_search_paths, resource_search_paths) => { assemblyPathsList = assembly_paths; nativeSearchPathsList = native_search_paths; resourceSearchPathsList = resource_search_paths; }); } finally { // Reset the error write to the one used before corehost_set_error_writer(previousErrorWriterPtr); GC.KeepAlive(errorWriter); } } catch (EntryPointNotFoundException entryPointNotFoundException) { throw new InvalidOperationException(SR.AssemblyDependencyResolver_FailedToLoadHostpolicy, entryPointNotFoundException); } catch (DllNotFoundException dllNotFoundException) { throw new InvalidOperationException(SR.AssemblyDependencyResolver_FailedToLoadHostpolicy, dllNotFoundException); } if (returnCode != 0) { // Something went wrong - report a failure throw new InvalidOperationException(SR.Format( SR.AssemblyDependencyResolver_FailedToResolveDependencies, componentAssemblyPath, returnCode, errorMessage)); } string[] assemblyPaths = SplitPathsList(assemblyPathsList); // Assembly simple names are case insensitive per the runtime behavior // (see SimpleNameToFileNameMapTraits for the TPA lookup hash). _assemblyPaths = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (string assemblyPath in assemblyPaths) { _assemblyPaths.Add(Path.GetFileNameWithoutExtension(assemblyPath) !, assemblyPath); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 } _nativeSearchPaths = SplitPathsList(nativeSearchPathsList); _resourceSearchPaths = SplitPathsList(resourceSearchPathsList); _assemblyDirectorySearchPaths = new string[1] { Path.GetDirectoryName(componentAssemblyPath) ! }; // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761 }
internal static extern IntPtr corehost_set_error_writer( corehost_error_writer_fn error_writer);