.net反射解析dll时 关联dll的加载

问题:

一个解析器:

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);
    }
}


posted on 2008-10-28 13:07  oyl  阅读(1131)  评论(0编辑  收藏  举报

导航