Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法在netcoreapp中加载具有特定于平台的dll的NuGet dll_C#_Nuget_.net Standard - Fatal编程技术网

C# 无法在netcoreapp中加载具有特定于平台的dll的NuGet dll

C# 无法在netcoreapp中加载具有特定于平台的dll的NuGet dll,c#,nuget,.net-standard,C#,Nuget,.net Standard,我无法使用netcoreapp中提供的ICompilationAssemblyResolver从其nuget包加载System.Data.Clientdll。程序集解析的大部分是从中借用的,在大多数情况下都非常有效。看起来是这样的: internal sealed class AssemblyResolver : IDisposable { private readonly ICompilationAssemblyResolver assemblyResolver; privat

我无法使用netcoreapp中提供的ICompilationAssemblyResolver从其nuget包加载
System.Data.Client
dll。程序集解析的大部分是从中借用的,在大多数情况下都非常有效。看起来是这样的:

internal sealed class AssemblyResolver : IDisposable
{
    private readonly ICompilationAssemblyResolver assemblyResolver;
    private readonly DependencyContext dependencyContext;
    private readonly AssemblyLoadContext loadContext;

    public AssemblyResolver(string path)
    {
        this.Assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path);
        this.dependencyContext = DependencyContext.Load(this.Assembly);

        this.assemblyResolver = new CompositeCompilationAssemblyResolver(new ICompilationAssemblyResolver[]
        {
            new AppBaseCompilationAssemblyResolver(Path.GetDirectoryName(path)),
            new ReferenceAssemblyPathResolver(),
            new PackageCompilationAssemblyResolver()
        });

        this.loadContext = AssemblyLoadContext.GetLoadContext(this.Assembly);
        this.loadContext.Resolving += OnResolving;
    }

    public Assembly Assembly { get; }

    public void Dispose()
    {
        this.loadContext.Resolving -= this.OnResolving;
    }

    private Assembly OnResolving(AssemblyLoadContext context, AssemblyName name)
    {
        bool NamesMatch(RuntimeLibrary runtime)
        {
            return string.Equals(runtime.Name, name.Name, StringComparison.OrdinalIgnoreCase);
        }

        RuntimeLibrary library =
        this.dependencyContext.RuntimeLibraries.FirstOrDefault(NamesMatch);
        if (library != null)
        {
            var wrapper = new CompilationLibrary(
                library.Type,
                library.Name,
                library.Version,
                library.Hash,
                library.RuntimeAssemblyGroups.SelectMany(g => g.AssetPaths),
                library.Dependencies,
                library.Serviceable);

            var assemblies = new List<string>();
            this.assemblyResolver.TryResolveAssemblyPaths(wrapper, assemblies);
            if (assemblies.Count > 0)
            {
                return this.loadContext.LoadFromAssemblyPath(assemblies[0]);
            }
        }

        return null;
    }
}
我不知道为什么在我指定了4.3.0的情况下它会尝试加载4.1.0,但我认为这有点冒险。我怀疑
packagecompilementassemblyresolver
仅在
lib
文件夹下查找,并且所讨论的包没有用于netstandard的包。但是,对于特定的运行时,它确实有一个:

有了这些信息,我创建了一个非常粗糙的AssemblyLoader,它在runtimes文件夹下查找nuget包,我能够加载dll并按预期运行我的程序

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.DotNet.PlatformAbstractions;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;

namespace Loader
{
    public class CrudeCompilationAssemblyResolver : ICompilationAssemblyResolver
    {
        private readonly string[] _nugetPackageDirectories;

        public CrudeCompilationAssemblyResolver()
        {
            var basePath = Environment.GetEnvironmentVariable("HOME");
            var defaultPath = Path.Combine(basePath, ".nuget", "packages");
            _nugetPackageDirectories = new [] { defaultPath };
        }

        public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
        {
            if (_nugetPackageDirectories == null || _nugetPackageDirectories.Length == 0 || !string.Equals(library.Type, "package", StringComparison.OrdinalIgnoreCase))
            {
                return false;
            }

            foreach (var directory in _nugetPackageDirectories)
            {
                string packagePath;

                var fullPath = Path.Combine(directory, library.Name, library.Version, "runtimes", "unix", "lib", "netstandard1.3", $"{library.Name}.dll");
                if (File.Exists(fullPath))
                {
                    assemblies.AddRange(new[] { fullPath });
                    return true;
                }
            }

            return false;        
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用Microsoft.DotNet.PlatformAbstractions;
使用Microsoft.Extensions.DependencyModel;
使用Microsoft.Extensions.DependencyModel.Resolution;
名称空间加载器
{
公共类CrudeCompilationAssemblyResolver:ICompilationAssemblyResolver
{
私有只读字符串[]\u NuGetPackageDirectory;
公共反编译程序集解析程序()
{
var basePath=Environment.GetEnvironmentVariable(“HOME”);
var defaultPath=Path.Combine(basePath、.nuget、.packages);
_NuGetPackageDirectory=new[]{defaultPath};
}
public bool TryResolveAssemblyPath(编译库、列表程序集)
{
如果(_NuGetPackageDirectory==null | | | _NuGetPackageDirectory.Length==0 | | |!string.Equals(library.Type,“package”,StringComparison.OrdinalIgnoreCase))
{
返回false;
}
foreach(在_numgetpackagedirectories中的var目录)
{
字符串封装路径;
var fullPath=Path.Combine(目录,library.Name,library.Version,“运行时”,“unix”,“lib”,“netstandard1.3”,“$”{library.Name}.dll”);
if(File.Exists(完整路径))
{
assemblies.AddRange(新[]{fullPath});
返回true;
}
}
返回false;
}
}
}
我的问题是:有没有更好的/官方认可的方法从nuget包加载这个麻烦的程序集?或者我需要让我的原油装载机少很多原油


完整回购在这里:

1。为什么要手动加载它?对于项目,NuGet将生成一个包含解析路径的资产文件(输入到deps.json generation)。2.编译程序集解析器并不意味着生成可以加载的程序集,只针对它们进行编译(=>编译器输入,如引用程序集,而不是实际实现)。我宁愿不手动加载它,我有点假设DependencyResolver会为我处理所有这些。我已经看到了
obj/project.assets.json
,我假设它用于生成
deps.json
,但我不确定如何使用它。我确实想知道如何使用CompliationAssemblyResolver。我最初使用的是依赖项解析程序中
RuntimeLibrary
上的
RuntimeAssemblyGroups
属性,但是
System.Data.SqlClient
的属性什么都没有,所以我去寻找其他解决方案,偶然发现了第一个链接。1。为什么要手动加载它?对于项目,NuGet将生成一个包含解析路径的资产文件(输入到deps.json generation)。2.编译程序集解析器并不意味着生成可以加载的程序集,只针对它们进行编译(=>编译器输入,如引用程序集,而不是实际实现)。我宁愿不手动加载它,我有点假设DependencyResolver会为我处理所有这些。我已经看到了
obj/project.assets.json
,我假设它用于生成
deps.json
,但我不确定如何使用它。我确实想知道如何使用CompliationAssemblyResolver。我最初使用的是依赖项解析程序中
RuntimeLibrary
上的
RuntimeAssemblyGroups
属性,但是
System.Data.SqlClient
的属性什么都没有,所以我去寻找其他解决方案,偶然发现了第一个链接。
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.DotNet.PlatformAbstractions;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;

namespace Loader
{
    public class CrudeCompilationAssemblyResolver : ICompilationAssemblyResolver
    {
        private readonly string[] _nugetPackageDirectories;

        public CrudeCompilationAssemblyResolver()
        {
            var basePath = Environment.GetEnvironmentVariable("HOME");
            var defaultPath = Path.Combine(basePath, ".nuget", "packages");
            _nugetPackageDirectories = new [] { defaultPath };
        }

        public bool TryResolveAssemblyPaths(CompilationLibrary library, List<string> assemblies)
        {
            if (_nugetPackageDirectories == null || _nugetPackageDirectories.Length == 0 || !string.Equals(library.Type, "package", StringComparison.OrdinalIgnoreCase))
            {
                return false;
            }

            foreach (var directory in _nugetPackageDirectories)
            {
                string packagePath;

                var fullPath = Path.Combine(directory, library.Name, library.Version, "runtimes", "unix", "lib", "netstandard1.3", $"{library.Name}.dll");
                if (File.Exists(fullPath))
                {
                    assemblies.AddRange(new[] { fullPath });
                    return true;
                }
            }

            return false;        
        }
    }
}