我有一个需要使用大量插件的程序。
每个插件都必须支持一个非常基本的接口,这个接口在一个DLL中定义(为了简化问题,我们称之为IBaseComponent)。
每个插件将位于特定目录(AppDirectory\plugin\plugin-type)。每个插件的插件dll可以具有任何名称 (AppDirectory\plugin\plugin-type\plugin-name.dll)。
因此,我需要检查每个插件子目录,找到每个支持IBaseComponent接口的类的插件,并实例化该类并调用一些插件函数。
好的,所有的事情都很好,但问题是我似乎遇到了一些奇怪的问题。
每个插件都需要在单独的插件文件夹中拥有Base.dll文件(而不仅仅是在将加载插件的程序中),并且似乎在动态加载具有需要被加载的dll的dll时,我会得到许多错误和警告。
我正在使用:
为了获取插件dll并使用:
为了获取dll中包含的类型,我正在遍历这些类型,并检查单个类型是否实现了IBaseComponent接口(表示这是一个有效的可加载类),代码如下:
然后使用:
为了获取模块中的类型,然后选择并加载与上述接口相同的支持接口的类。
问题似乎出现在我使用以下内容时:
我不确定为什么会出现这种情况。DLL文件在插件文件夹中,包含IBaseComponent接口的DLL文件也在每个插件目录中。我做错了吗?
此外,是否需要在每个插件子目录中保留一个包含IBaseComponent的DLL副本以及程序本身使用的DLL副本?或者我做错了什么,可以允许我删除此要求?
我知道MEF是我想要使用的东西,但不幸的是,因为我需要在.net 2.0上支持它,所以无法使用MEF。
每个插件都必须支持一个非常基本的接口,这个接口在一个DLL中定义(为了简化问题,我们称之为IBaseComponent)。
每个插件将位于特定目录(AppDirectory\plugin\plugin-type)。每个插件的插件dll可以具有任何名称 (AppDirectory\plugin\plugin-type\plugin-name.dll)。
因此,我需要检查每个插件子目录,找到每个支持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文件在插件文件夹中,包含IBaseComponent接口的DLL文件也在每个插件目录中。我做错了吗?
此外,是否需要在每个插件子目录中保留一个包含IBaseComponent的DLL副本以及程序本身使用的DLL副本?或者我做错了什么,可以允许我删除此要求?
我知道MEF是我想要使用的东西,但不幸的是,因为我需要在.net 2.0上支持它,所以无法使用MEF。