动态加载DLL

时间:2011-02-25 21:57:30

标签: c# .net dll plugins interface

我有一个需要使用大量插件的程序。

每个插件必须支持一个非常基本的接口,此接口在DLL中定义(为了简单起见,IBaseComponent)。

每个插件都在特定目录中(AppDirectory \ plugin \ plugin-type)。 每个插件都可以有插件的dll的任何名称(AppDirectory \ plugin \ plugin-type \ plugin-name.dll)。

所以我需要检查每个plugin子目录,找到每个插件都有一个支持IBaseComponent接口的类,实例化该类并调用插件上的一些函数。

好吧,一切都很好,花花公子,这一切都不是特别难。但问题是我似乎遇到了一些奇怪的问题。

每个插件都需要在各个插件文件夹中包含Base.dll文件(而不是仅在将要加载插件的程序中),而且似乎我在动态加载dll时会遇到很多错误和警告dll也需要加载。

我正在使用:

pluginModule = System.Reflection.Assembly.ReflectionOnlyLoadFrom(PathToAssembly);

为了获取插件dll并使用:

types = moduleAssembly.GetTypes();

以获取dll中包含的类型。 我正在遍历类型并检查单个类型是否属于IBaseComponent接口(表示这对于加载类是有效的):

if (type.GetInterface("FrameworkNameSpace.IBaseComponent") != null)
    //it's of the IBaseComponent interface

稍后,为了从我使用的dll实际创建类的实例:

pluginModule = System.Reflection.Assembly.LoadFrom(PathToAssembly);

然后使用:

types = component.GetTypes();

为了获取模块中的类型,然后选择并加载支持与上面相同的接口的类。

当我使用时,问题似乎就出现了:

types = component.GetTypes();

当实际尝试加载课程时,而不是简单地看着它。 (因此我对 LoadFrom ReflectionOnlyLoad 的不同用法)

我在GetTypes调用中收到的异常(在第二个插件上,但从来没有第一个!)是:

{"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information."}

将LoaderExceptions属性设置为:

{"The specified module could not be found. (Exception from HRESULT: 0x8007007E)":null}

我不确定为什么会这样。 DLL位于plugin文件夹中,包含IBaseComponent接口的DLL也位于每个插件目录中。我是以错误的方式解决这个问题吗?

我是否需要在每个插件子目录中保留包含IBaseComponent的DLL副本以及程序本身使用的副本,或者我是否正在做错误的操作以允许我删除此要求?

我知道MEF是我想要使用的,但不幸的是因为我需要在.net 2.0上支持这个。我无法使用MEF。

1 个答案:

答案 0 :(得分:5)

这是LoadLibrary()失败。听我说你的插件依赖于一些非托管DLL。是的,Windows将很难找到这些DLL,它没有理由查看插件目录。也许它第一次工作,因为您的应用程序的默认目录恰好设置为正确的目录。这也是解决方法,使用Environment.CurrentDirectory。

确切地找出无法找到哪些依赖关系是关键。未管理的不会出现在fuslogvw.exe中,您可以从SysInternals的ProcMon实用程序中删除它。