【问题标题】:Complicated API issue with calling assemblies dynamically‏动态调用程序集的复杂 API 问题
【发布时间】:2011-02-13 19:48:45
【问题描述】:

我有一个有趣的挑战,我想知道这里是否有人可以给我一些指导。

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

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

我可以使用我的 API 创建程序集,将文件复制到本地硬盘驱动器中的文件夹,并将我的应用程序配置为使用反射从实现的接口 (IDataManipulate.Execute) 调用特定函数。


问题:

由于应用程序将安装在网络中的多个工作站中,因此无法将用户将创建的插件 dll 复制到每台机器上。

我尝试过的解决方案:

解决方案 1
将 API dll 复制到网络共享。

问题:
需要 AllowPartiallyTrustedCallersAttribute,这需要 .Net 唱歌,我不能强迫我的用户这样做。

解决方案 2(首选)
将dll对象序列化,保存到数据库,反序列化后调用IDataManipulate.Execute。

问题:
反序列化后,我尝试将其转换为 IDataManipulate 对象,但在查找实际的 dll 文件时返回错误。

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

问题:
dll可能有依赖,不知道能不能检测到。


任何建议将不胜感激。

谢谢

【问题讨论】:

    标签: .net api reflection assemblies plugins


    【解决方案1】:

    我以前做过“解决方案 3”。我们将 DLL 文件存储在带有“最后修改”时间戳的数据库表中。这样您就可以在应用启动时判断本地文件是否需要更新。

    您可以调用Assembly.GetReferencedAssemblies 从程序集中获取依赖项列表。这假定插件 DLL 不使用反射来动态加载随机程序集,但这应该是可以接受的。

    另一种选择是使用AppDomain.AssemblyResolve 事件。此事件不会在启动时下载所有插件 DLL,而是让您只下载实际需要的 DLL。

    【讨论】:

    • @David,您是否尝试实施解决方案 #2?因为如果我可以避免在运行时创建 DLL,那将是理想的。
    • 如果您使用 AssemblyResolve 事件,您可以返回从任何流对象加载的程序集对象。这样您就可以从数据库中加载它,而不必先将其保存到磁盘。
    【解决方案2】:

    您可以将它们复制到网络共享,然后当您的应用启动或需要加载插件时,您可以将日期与您在本地保存的日期进行比较,如果它较新,则将其复制到本地..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多