动态调用程序集的复杂 API 问题
我面临一个有趣的挑战,我想知道这里是否有人可以给我一些指导。
我正在编写一个在网络上运行并使用 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可能有依赖关系,我不知道我是否能检测到。
任何建议将不胜感激。
I have an interesting challenge that I'm wondering if anyone here can give me some direction.
I'm writing a .Net windows forms application that runs on a network and uses an SQL Server to save and pull data.
I want to offer a mini "plugin" API, where developers can build their own assemblies and implement a specific interface (IDataManipulate). These assemblies then can be used by my application to call the interface functions and do something.
I can create assemblies using my API, copy the file to a folder in my local hard drive and configure my application to use Reflection to call a specific function from the implemented interface (IDataManipulate.Execute).
The problem:
Since the application will be installed in multiple workstations in the network, is impossible to copy the plugin dlls the users will create to each machine.
Solutions I tried:
Solution 1
Copy the API dll to a network share.
Problem:
Requires AllowPartiallyTrustedCallersAttribute, which requires .Net singing, which I can't force from my users.
Solution 2 (preferred)
Serialize the dll object, save it to the database, deserialize it and call IDataManipulate.Execute.
Problem:
After deserialization, I try cast it to a IDataManipulate object but returns an error looking for the actual dll file.
Solution 3
Save the dll bytes as byte[] to the database and recreate the dll at the local PC every time the user starts my application.
Problem:
Dll may have dependencies, which I don't know if I can detect.
Any suggestions will be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我以前做过“解决方案3”。我们将 DLL 文件存储在带有“上次修改”时间戳的数据库表中。这样您就可以知道应用程序启动时是否需要更新本地文件。
您可以调用 Assembly.GetReferencedAssemblies< /a> 从程序集中获取依赖项列表。这假设插件 DLL 不使用反射来动态加载随机程序集,但这应该是可以接受的。
另一种选择是使用 AppDomain.AssemblyResolve 事件。此事件不会让您在启动时下载所有插件 DLL,而是只下载实际需要的 DLL。
I've done "Solution 3" before. We stored the DLL files in a database table with a "last modified" timestamp. That way you could tell if the local file needed to be updated when the app started.
You can call Assembly.GetReferencedAssemblies to get the list of dependencies from an assembly. This assumes that the plugin DLL doesn't use reflection to dynamically load a random assembly, but that should be acceptable.
Another option is to use the AppDomain.AssemblyResolve event. Instead of downloading all of the plugin DLLs on startup, this event would let you only download the DLLs that are actually needed.
您可以将它们复制到网络共享,然后当您的应用程序启动或需要加载插件时,您可以将日期与本地保存的日期进行比较,如果较新,则将其复制到本地。
You could copy them to a network share, then when your app starts up or you need to load the plugins you could compare the date against the one you hold locally, if it is newer then copy it over locally..