使用VS2017 RC,.NET核心
我正在尝试从文件加载程序集。此程序集的依赖项位于同一文件夹中。
我正在使用AssemblyLoadContext.Default.LoadFromAssemblyPath。
我意识到LoadFromAssemblyPath以独占方式加载请求的程序集,忽略它的依赖项;任何遍历程序集类型的尝试都会失败,并返回一个System.Reflection.ReflectionTypeLoadException。
LoaderExceptions包含System.IO.FileNotFoundException的列表。
我很好奇为什么会这样,因为所有需要的文件都在同一个文件夹中。
我还尝试加载文件夹中的所有*.dll文件,但由于System.IO.FileLoadException,有些文件意外失败。
我做错了什么?
编辑:我不想依赖于.deps文件(因此排除了DependencyContext)。有可能吗?
发布于 2016-12-02 06:42:47
我的工作就是注册一个解析事件的句柄,并在LoadFromAssemblyPath需要依赖项时按需加载所需的程序集。请注意,这是我通过几个小时的试验和错误得出的解决方案,因此它可能不是最理想的方法。不过,现在它对我来说已经可以用了。下面是我的代码:
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部分,但它就像一个缓存,避免了一遍又一遍地重新加载相同的程序集。所以我留着它。
发布于 2020-02-23 02:07:43
在.Net核心3.0+中有一个很大的增强,如下所示的连接AssemblyLoadContext.Default.Resolving事件,所有的依赖项都将被解析和加载:
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中的依赖项
var resolver = new AssemblyDependencyResolver(pluginPath);
AssemblyLoadContext.Default.Resolving += (context, name) => {
string assemblyPath = resolver.ResolveAssemblyToPath(name);
if (assemblyPath != null)
return context.LoadFromAssemblyPath(assemblyPath);
return null;
};https://stackoverflow.com/questions/40908568
复制相似问题