/// <summary> /// Initializes a new instance of the <see cref="NetCoreAssemblyDependencyResolver"/> class. /// </summary> /// <param name="assemblyFilePath">The path to the assembly</param> /// <param name="internalDiagnosticsMessageSink">An optional message sink for use with internal diagnostics messages; /// may pass <c>null</c> for no internal diagnostics messages</param> public NetCoreAssemblyDependencyResolver(string assemblyFilePath, IMessageSink internalDiagnosticsMessageSink) { this.internalDiagnosticsMessageSink = internalDiagnosticsMessageSink; var assembly = LoadFromAssemblyPath(assemblyFilePath); assemblyFolder = Path.GetDirectoryName(assemblyFilePath); assemblyResolver = new XunitPackageCompilationAssemblyResolver(); dependencyContext = DependencyContext.Load(assembly); var compatibleRuntimes = default(HashSet <string>); var currentRuntime = RuntimeEnvironment.GetRuntimeIdentifier(); var fallbacks = dependencyContext.RuntimeGraph.FirstOrDefault(x => string.Equals(x.Runtime, currentRuntime, StringComparison.OrdinalIgnoreCase)); if (fallbacks != null) { compatibleRuntimes = new HashSet <string>(fallbacks.Fallbacks, StringComparer.OrdinalIgnoreCase); } else { compatibleRuntimes = new HashSet <string>(StringComparer.OrdinalIgnoreCase); } compatibleRuntimes.Add(currentRuntime); compatibleRuntimes.Add(string.Empty); managedAssemblyCache = new Dictionary <string, Assembly>(StringComparer.OrdinalIgnoreCase); managedAssemblyMap = dependencyContext.RuntimeLibraries .Where(lib => lib.RuntimeAssemblyGroups?.Count > 0) .Select(lib => Tuple.Create(lib, lib.RuntimeAssemblyGroups.FirstOrDefault(libGroup => compatibleRuntimes.Contains(libGroup.Runtime)))) .Where(tuple => tuple.Item2?.AssetPaths != null) .SelectMany(tuple => tuple.Item2.AssetPaths.Where(x => x != null).Select(path => Tuple.Create(Path.GetFileNameWithoutExtension(path), Tuple.Create(tuple.Item1, tuple.Item2)))) .ToDictionaryIgnoringDuplicateKeys(tuple => tuple.Item1, tuple => tuple.Item2, StringComparer.OrdinalIgnoreCase); if (internalDiagnosticsMessageSink != null) { internalDiagnosticsMessageSink.OnMessage(new DiagnosticMessage($"[NetCoreAssemblyDependencyResolver..ctor] Managed assembly map includes: {string.Join(",", managedAssemblyMap.Keys.Select(k => $"'{k}'").OrderBy(k => k, StringComparer.OrdinalIgnoreCase))}")); } unmanagedAssemblyCache = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); unmanagedAssemblyMap = dependencyContext.RuntimeLibraries .Where(lib => lib.NativeLibraryGroups?.Count > 0) .Select(lib => Tuple.Create(lib, lib.NativeLibraryGroups.FirstOrDefault(libGroup => compatibleRuntimes.Contains(libGroup.Runtime)))) .Where(tuple => tuple.Item2?.AssetPaths != null) .SelectMany(tuple => tuple.Item2.AssetPaths.Where(x => x != null).Select(path => Tuple.Create(Path.GetFileName(path), Tuple.Create(tuple.Item1, tuple.Item2)))) .ToDictionaryIgnoringDuplicateKeys(tuple => tuple.Item1, tuple => tuple.Item2, StringComparer.OrdinalIgnoreCase); if (internalDiagnosticsMessageSink != null) { internalDiagnosticsMessageSink.OnMessage(new DiagnosticMessage($"[NetCoreAssemblyDependencyResolver..ctor] Unmanaged assembly map includes: {string.Join(",", unmanagedAssemblyMap.Keys.Select(k => $"'{k}'").OrderBy(k => k, StringComparer.OrdinalIgnoreCase))}")); } Default.Resolving += OnResolving; }
public DependencyContextAssemblyCache(string assemblyFolder, DependencyContext dependencyContext, IMessageSink internalDiagnosticsMessageSink, Platform?operatingSystemPlatform = null, string currentRuntimeIdentifier = null, IFileSystem fileSystem = null) { this.assemblyFolder = assemblyFolder; this.dependencyContext = dependencyContext; this.internalDiagnosticsMessageSink = internalDiagnosticsMessageSink; this.operatingSystemPlatform = operatingSystemPlatform ?? RuntimeEnvironment.OperatingSystemPlatform; this.currentRuntimeIdentifier = currentRuntimeIdentifier ?? RuntimeEnvironment.GetRuntimeIdentifier(); this.fileSystem = fileSystem ?? new FileSystemWrapper(); fallbackRuntimeIdentifier = new Lazy <string>(() => GetFallbackRuntime(this.currentRuntimeIdentifier)); assemblyResolver = new XunitPackageCompilationAssemblyResolver(internalDiagnosticsMessageSink, fileSystem); if (internalDiagnosticsMessageSink != null) { internalDiagnosticsMessageSink.OnMessage(new _DiagnosticMessage($"[DependencyContextAssemblyCache..ctor] Runtime graph: [{string.Join(",", dependencyContext.RuntimeGraph.Select(x => $"'{x.Runtime}'"))}]")); } var compatibleRuntimes = GetCompatibleRuntimes(dependencyContext); if (internalDiagnosticsMessageSink != null) { internalDiagnosticsMessageSink.OnMessage(new _DiagnosticMessage($"[DependencyContextAssemblyCache..ctor] Compatible runtimes: [{string.Join(",", compatibleRuntimes.Select(x => $"'{x}'"))}]")); } managedAssemblyCache = new ConcurrentDictionary <string, Assembly>(StringComparer.OrdinalIgnoreCase); managedAssemblyMap = dependencyContext.RuntimeLibraries .Where(lib => lib.RuntimeAssemblyGroups?.Count > 0) .Select(lib => compatibleRuntimes.Select(runtime => Tuple.Create(lib, lib.RuntimeAssemblyGroups.FirstOrDefault(libGroup => string.Equals(libGroup.Runtime, runtime)))) .FirstOrDefault(tuple => tuple.Item2?.AssetPaths != null)) .Where(tuple => tuple != null) .SelectMany(tuple => tuple.Item2.AssetPaths.Where(x => x != null) .Select(path => Tuple.Create(Path.GetFileNameWithoutExtension(path), Tuple.Create(tuple.Item1, tuple.Item2)))) .ToDictionaryIgnoringDuplicateKeys(tuple => tuple.Item1, tuple => tuple.Item2, StringComparer.OrdinalIgnoreCase); if (internalDiagnosticsMessageSink != null) { internalDiagnosticsMessageSink.OnMessage(new _DiagnosticMessage($"[DependencyContextAssemblyCache..ctor] Managed assembly map: [{string.Join(",", managedAssemblyMap.Keys.Select(k => $"'{k}'").OrderBy(k => k, StringComparer.OrdinalIgnoreCase))}]")); } unmanagedDllFormats = GetUnmanagedDllFormats().ToArray(); unmanagedAssemblyCache = new ConcurrentDictionary <string, string>(StringComparer.OrdinalIgnoreCase); unmanagedAssemblyMap = dependencyContext.RuntimeLibraries .Select(lib => compatibleRuntimes.Select(runtime => Tuple.Create(lib, lib.NativeLibraryGroups.FirstOrDefault(libGroup => string.Equals(libGroup.Runtime, runtime)))) .FirstOrDefault(tuple => tuple.Item2?.AssetPaths != null)) .Where(tuple => tuple != null) .SelectMany(tuple => tuple.Item2.AssetPaths.Where(x => x != null) .Select(path => Tuple.Create(Path.GetFileName(path), Tuple.Create(tuple.Item1, tuple.Item2)))) .ToDictionaryIgnoringDuplicateKeys(tuple => tuple.Item1, tuple => tuple.Item2, StringComparer.OrdinalIgnoreCase); if (internalDiagnosticsMessageSink != null) { internalDiagnosticsMessageSink.OnMessage(new _DiagnosticMessage($"[DependencyContextAssemblyCache..ctor] Unmanaged assembly map: [{string.Join(",", unmanagedAssemblyMap.Keys.Select(k => $"'{k}'").OrderBy(k => k, StringComparer.OrdinalIgnoreCase))}]")); } }