首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET内核中的汇编加载

.NET内核中的汇编加载
EN

Stack Overflow用户
提问于 2016-12-01 18:46:00
回答 2查看 7.1K关注 0票数 5

使用VS2017 RC,.NET核心

我正在尝试从文件加载程序集。此程序集的依赖项位于同一文件夹中。

我正在使用AssemblyLoadContext.Default.LoadFromAssemblyPath

我意识到LoadFromAssemblyPath以独占方式加载请求的程序集,忽略它的依赖项;任何遍历程序集类型的尝试都会失败,并返回一个System.Reflection.ReflectionTypeLoadException

LoaderExceptions包含System.IO.FileNotFoundException的列表。

我很好奇为什么会这样,因为所有需要的文件都在同一个文件夹中。

我还尝试加载文件夹中的所有*.dll文件,但由于System.IO.FileLoadException,有些文件意外失败。

我做错了什么?

编辑:我不想依赖于.deps文件(因此排除了DependencyContext)。有可能吗?

EN

回答 2

Stack Overflow用户

发布于 2016-12-02 06:42:47

我的工作就是注册一个解析事件的句柄,并在LoadFromAssemblyPath需要依赖项时按需加载所需的程序集。请注意,这是我通过几个小时的试验和错误得出的解决方案,因此它可能不是最理想的方法。不过,现在它对我来说已经可以用了。下面是我的代码:

代码语言:javascript
复制
    AssemblyLoadContext.Default.Resolving += (context, name) =>
    {
        // avoid loading *.resources dlls, because of: https://github.com/dotnet/coreclr/issues/8416
        if (name.Name.EndsWith("resources"))
        {
            return null;
        }

        var dependencies = DependencyContext.Default.RuntimeLibraries;
        foreach (var library in dependencies)
        {
            if (IsCandidateLibrary(library, name))
            {
                return context.LoadFromAssemblyName(new AssemblyName(library.Name));
            }
        }

        var foundDlls = Directory.GetFileSystemEntries(new FileInfo(<YOUR_PATH_HERE>).FullName, name.Name + ".dll", SearchOption.AllDirectories);
        if (foundDlls.Any())
        {
            return context.LoadFromAssemblyPath(foundDlls[0]);
        }

        return context.LoadFromAssemblyName(name);
    };
}
private static bool IsCandidateLibrary(RuntimeLibrary library, AssemblyName assemblyName)
{
    return (library.Name == (assemblyName.Name))
            || (library.Dependencies.Any(d => d.Name.StartsWith(assemblyName.Name)));
}

IsCandidateLibrary()位从那里产生:http://www.michael-whelan.net/replacing-appdomain-in-dotnet-core/

我认为你可以省略这个部分和整个DependencyContext部分,但它就像一个缓存,避免了一遍又一遍地重新加载相同的程序集。所以我留着它。

票数 9
EN

Stack Overflow用户

发布于 2020-02-23 02:07:43

在.Net核心3.0+中有一个很大的增强,如下所示的连接AssemblyLoadContext.Default.Resolving事件,所有的依赖项都将被解析和加载:

代码语言:javascript
复制
 AssemblyLoadContext.Default.Resolving += (context, name) => {
                string assemblyPath = $"{pluginFolder}\\{name.Name}.dll";                
                if (assemblyPath != null)   
                    return context.LoadFromAssemblyPath(assemblyPath);     
                return null;
            };

记住要定义变量pluginFolder

Solution2

您可以使用AssemblyDependencyResolver类并解析依赖项,包括.deps.json中的依赖项

代码语言:javascript
复制
  var resolver = new AssemblyDependencyResolver(pluginPath);            

  AssemblyLoadContext.Default.Resolving += (context, name) => {

                string assemblyPath = resolver.ResolveAssemblyToPath(name);               
                if (assemblyPath != null)   
                    return context.LoadFromAssemblyPath(assemblyPath);     
                return null;
            };
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40908568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档