问题:
一个解析器:
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;
classProgram
{
staticvoid Main(string[] args)
{
string filename = args[0];
Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
Console.WriteLine("Opened assembly:{0}", filename);
foreach (Type t in a.GetTypes())
{
Console.WriteLine(" " + t.FullName);
}
}
}
使用:
type_sniff.exe type_sniff.exe
Openedassembly:type_sniff.exe
Program
但是当dll中有关联时,如:
// defined in a.dll
publicclass Foo
{
public Foo()
{
}
}
// defined in b.dll, compiled as /r:a.dll
publicclass Bar : Foo
{
Bar()
{
}
}
运行: type_sniff.exe b.dll
C:\bug\type_sniff\type_sniff\bin\Debug>type_sniff.exe b.dll Opened assembly:b.dll Unhandled Exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. at System.Reflection.Module.GetTypesInternal(StackCrawlMark& stackMark) at System.Reflection.Assembly.GetTypes() at Program.Main(String[] args)Exception 的message为:{"Cannot resolve dependency to assembly 'a, Version=2.1.0.0, Culture=neutral, PublicKeyToken=ebb8d478f63174c0'
because it has not been preloaded. When using the ReflectionOnly APIs,
dependent assemblies must be pre-loaded or loaded on demand through
the ReflectionOnlyAssemblyResolve event.":"a, Version=2.1.0.0, Culture=neutral, PublicKeyToken=ebb8d478f63174c0"}
解决方法:
在ReflectionOnlyAssemblyResolve event时加入需要加载的dll进来, 这里假设dll都在working directory
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Text;
classProgram
{
staticvoid Main(string[] args)
{
string filename = args[0];
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += newResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
Console.WriteLine("Opened assembly:{0}", filename);
foreach (Type t in a.GetTypes())
{
Console.WriteLine(" " + t.FullName);
}
}
staticAssembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}
}