C# 在ReflectionOnlyLoadFrom之后无法从程序集获取类型
我在网站上查阅了Marius Bancila标题为“将程序集从任何地方加载到新AppDomain”的代码,但我测试了错误,如所附图片所示,目前我不知道如何解决,希望您能提供帮助,谢谢 链接代码 试验 错误 未设置组件分解器 Marius的代码在C# 在ReflectionOnlyLoadFrom之后无法从程序集获取类型,c#,reflection,C#,Reflection,我在网站上查阅了Marius Bancila标题为“将程序集从任何地方加载到新AppDomain”的代码,但我测试了错误,如所附图片所示,目前我不知道如何解决,希望您能提供帮助,谢谢 链接代码 试验 错误 未设置组件分解器 Marius的代码在AssemblyReflectionProxy中有一个缺陷,即如果调用LoadAssembly则未设置程序集解析器,而Reflect则没有设置 根据子应用程序域的创建方式,加载程序集时,它可能只能访问创建期间指定的文件夹。如果需要在别处探测程序集或其依赖
AssemblyReflectionProxy
中有一个缺陷,即如果调用LoadAssembly
则未设置程序集解析器,而Reflect
则没有设置
根据子应用程序域的创建方式,加载程序集时,它可能只能访问创建期间指定的文件夹。如果需要在别处探测程序集或其依赖项,则需要程序集解析器。当.NET为域查找程序集时,它将按照程序集的ReflectionOnlyAssemblyResolve
事件中的指定调用您的处理程序。如果未指定,或者冲突解决程序找不到程序集,它将冒泡并引发加载失败异常
我建议您将代码更改为:
public class AssemblyReflectionProxy : MarshalByRefObject
{
private string _assemblyPath;
public void LoadAssembly(String assemblyPath)
{
try
{
_assemblyPath = assemblyPath;
Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}
catch (FileNotFoundException)
{
// Continue loading assemblies even if an assembly
// cannot be loaded in the new AppDomain.
}
}
…致:
public class AssemblyReflectionProxy : MarshalByRefObject
{
private string _assemblyPath;
public void LoadAssembly(String assemblyPath)
{
try
{
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve // <---- add me
+= OnReflectionOnlyResolve;
_assemblyPath = assemblyPath;
Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}
catch (FileNotFoundException)
{
// Continue loading assemblies even if an assembly
// cannot be loaded in the new AppDomain.
}
}
然后修改OnReflectionOnlyResolve,使其类似于以下内容:
private Assembly OnReflectionOnlyResolve(ResolveEventArgs args, DirectoryInfo directory)
{
Assembly loadedAssembly =
AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies()
.FirstOrDefault(
asm => string.Equals(asm.FullName, args.Name,
StringComparison.OrdinalIgnoreCase));
if (loadedAssembly != null)
{
return loadedAssembly;
}
foreach (var tryFolder in ResolvePaths)
{
var asmName = args.Name.Split(',');
var assemblyPath = Path.Combine(tryFolder, asmName[0] + ".dll");
if (!File.Exists(assemblyPath))
return null;
return Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}
}
名字里有什么?
这两篇文章在使用ReflectionOnlyLoad
时都忽略了指出细节。虽然他的代码是为“代码生成器”编写的,但我不禁想知道,这两篇文章中的“加载程序集
…到新的AppDomain”可能多少都需要解释
ReflectionOnlyLoad
的目的就是为了反射。如果通过此方法加载程序集,则无法在其中执行任何代码。另外,对于包括我在内的大多数程序集反射器程序员来说,一开始有些令人惊讶的是,调用GetCustomAttributes
也会这样做(因为它试图“实例化”程序集中的类型)
如果您正在编写自己的插件系统,其中每个插件都有自己的应用程序域,Assembly
反射和加载方法对于插件系统加载管道的不同阶段非常有用:
ReflectionOnlyLoad
检查插件是否有效;也许您希望安全地运行一些安全检查,因为在此阶段没有任何插件代码可以运行加载/并执行代码
这回答了你的问题吗?我和你一样编辑过,但还是有错误。不介意,你能帮我编辑一下吗,对不起,我不是。链接代码:@NhuTruong请参阅上面的“添加解决路径的规定”更新抱歉@MickyD,我的问题仍然没有解决。@NhuTruong请注意。因此,这并不是一个解决第三方代码中所有问题的场所。也要注意。我引用。@NhuTruong我鼓励您首先访问Sacha的代码并相应地修改它。另一个代码库更复杂,可能有问题
public List<string> ResolvePaths { get; set; }
private Assembly OnReflectionOnlyResolve(ResolveEventArgs args, DirectoryInfo directory)
{
Assembly loadedAssembly =
AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies()
.FirstOrDefault(
asm => string.Equals(asm.FullName, args.Name,
StringComparison.OrdinalIgnoreCase));
if (loadedAssembly != null)
{
return loadedAssembly;
}
foreach (var tryFolder in ResolvePaths)
{
var asmName = args.Name.Split(',');
var assemblyPath = Path.Combine(tryFolder, asmName[0] + ".dll");
if (!File.Exists(assemblyPath))
return null;
return Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}
}