动态加载程序集AssemblyResolve问题

时间:2010-05-24 14:35:51

标签: .net api reflection plugins assemblies

注意: 这是我上一篇文章的延续: Complicated API issue with calling assemblies dynamically‏


我正在编写一个在网络上运行的.Net Windows窗体应用程序,并使用SQL Server来保存和提取数据。

我想提供一个迷你“插件”API,开发人员可以在其中构建自己的程序集并实现特定的接口(IDataManipulate)。然后,我的应用程序可以使用这些程序集来调用IDataManipulate.Execute()。

我决定采用解决方案#3:

  

将dll字节保存为byte []到数据库,并在每次用户启动应用程序时在本地PC上重新创建dll。

所以这就是我正在做的事情:

  • 我的应用程序提示用户上传实现我的API接口的.Net程序集(IDataManipulate)(“main”asseembly)并将字节保存在数据库中。
  • 然后,使用Assembly.GetReferencedAssemblies我得到一个引用的程序集列表,并将它们的字节保存在数据库中(“引用的”程序集),假设用户在同一文件夹中提供了实际文件。
    问题:如何从Assembly.GetReferencedAssemblies列表中识别系统程序集并将其排除?
  • 当app运行时,我从数据库中获取主程序集的字节,使用Assembly.Load(byte [])创建程序集并使用CreateInstance(type),其中type是实现IDataManipulate的对象(所以我可以调用IDataManipulate.Execute())。
  • 然后我使用AppDomain.AssemblyResolve事件使用Aseembly.Load(byte [])
  • 从数据库加载引用程序集的字节

一切正常; dll已加载,我可以调用IDataManipulate.Execute(),除了这个问题:

问题

当我从主程序集调用IDataManipulate.Execute()时,出现错误,例如“我无法从此程序集加载类型xxxx”。无法加载的类型属于其中一个引用的程序集而不是主程序集。

为什么会这样?

有什么建议吗?

由于

2 个答案:

答案 0 :(得分:1)

要回答第一个问题,您可以检查引用的程序集的位置,如果它位于同一文件夹中,则只将其添加到数据库中。

答案 1 :(得分:1)

有点晚了,但你也可以查看程序集的PublicKeyToken。我相信.net存在三个令牌。您可以通过查看Windows框架文件夹找到它们。这样,如果需要,可以在其他文件夹中包含程序集。

那就是说,我可能会要求开发人员将它们放在同一个文件夹中。如果他们决定包括像Infragistics或诸如此类的大型第三方库。这样他们显然必须在导入之前将程序集移动到文件夹,让他们知道他们正在做什么。