访问驻留在插件dll中的自定义对象 [英] Access a custom object that resides in plug in dll

查看:161
本文介绍了访问驻留在插件dll中的自定义对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个独立的应用程序,可以从数据库中导出一些数据。在这个程序中,我有一个自定义对象ExportParams,它保存数据库信息,服务器,数据库名称等,它们可以来自用户界面,配置文件或命令提示符。我现在需要将此独立应用程序更改为插件。我已经转换为插件的用户界面可以毫无问题地运行。我遇到的问题是如何从主窗体访问此自定义对象,以便我可以将命令提示符或配置文件中的参数发送到插件中?

解决方案

< blockquote>使用反射的常见错误是按名称提取某些类型和类型成员。这是不可支持的,因为这些名称变成了神奇的词汇:任何重构都可能导致这些名称发生变化;并且代码和数据中声明的名称之间的不匹配不能被检测为编译错误。



同时,正确的方法是100%可靠的并且可以承受任何重命名。您可以这样做:



定义一些插件界面。它可以在主机应用程序和插件程序集引用的某个程序集中定义。更棘手的方法是在主机应用程序程序集中正确定义它。它总是可以完成的,因为应用程序组件可以由插件组件引用,就像它是一个库一样;它不会创建任何循环依赖,因为应用程序程序集不依赖于插件,只有运行时依赖于它们。



现在,当你加载插件时-in assembly,主机应用程序可以扫描其类型并确定实现插件接口的类型。这可以使用此功能完成:

http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom%28v=vs.110%29.aspx [ ^ ]。



我做得更好。我定义了一个特殊的程序集级别属性( System.AttributeTargets.Assembly ;请参阅http://msdn.microsoft.com/en-us/library/system.attributeusageattribute%28v=vs.110%29.aspx [ ^ ], http://msdn.microsoft.com/ en-us / library / system.attributetargets%28v = vs.110%29.aspx [ ^ ])仅用于声明应该检查哪些类型实现插件接口。然后排除所有程序集类型列表中的搜索。



当在runtine期间加载的插件集应该变化时出现更大的问题,即你需要卸载一些程序集。出于重要的可靠性原因,.NET不允许这样做。因此,您需要在可以完全卸载的单独应用程序域中加载插件,但它需要与IPC一起工作才能跨越应用程序域之间的界限。您可以在我过去的答案中找到详细信息:

通过它的字符串表示从集合中收集类型 [ ^ ],

C#Reflection InvokeMember on existing instance [ ^ ],

项目和DLL:如何保持它们可管理? [ ^ ],

动态加载用户控件 [ ^ ],

使用CodeDom生成代码 [ ^ ],

AppDomain拒绝加载程序集 [ ^ ],

的Cre吃了使用Reloadable Plugins的WPF应用程序...... [ ^ ]。



-SA


I have a standalone application that exports some data from a database. In this program I have a custom object, ExportParams, that keeps the database information, server, database name etc, that can come from the user interface, a config file or from the command prompt. I now need to change this standalone application into a plugin. The user interface I have converted into a plugin and can run without issue. The issue I am having is how do I access this custom object from the main form so I can send in the parameters from the command prompt or config file into the plugin?

解决方案

The common mistake in using reflection is extracting some types and type members by names. This is not supportable, because those names become "magic words": any refactorization can lead to change of these names; and the mismatch between names declared in code and in data cannot be detected as a compilation error.

At the same time, right approach is 100% reliable and will withstand any renaming. Here is what you can do:

Define some plug-in interface. It can be defined in some assembly referenced by both host application and plug-in assemblies. A bit more tricky way is to define it right in the host application assembly. It always can be done, because application assembly can be referenced by a plug-in assembly exactly as it was a library; it would not create any circular dependencies, because the application assembly does not depend on plug-ins, only the runtime depends on them.

Now, when you load the plug-in assembly, the host application can scan its types and determine the one(s) implementing the plug-in interface(s). This can be done using this function:
http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom%28v=vs.110%29.aspx[^].

I do even better. I define a special assembly-level attribute (System.AttributeTargets.Assembly; please see http://msdn.microsoft.com/en-us/library/system.attributeusageattribute%28v=vs.110%29.aspx[^], http://msdn.microsoft.com/en-us/library/system.attributetargets%28v=vs.110%29.aspx[^]) used just to claim which type(s) should be checked as implementing the plug-in interfaces. Then the search in the list of all assembly types is excluded.

The bigger problems appear when the set of loaded plug-ins should vary during runtine, that is, when you need to unload some assemblies. For important reliability reasons, .NET does not allow that. So, you would need to load plug-ins in separate Application Domains which can be fully unloaded, but it requires working with IPC, to reach through the boundaries between Application Domains. You can find the detail in my past answers:
Gathering types from assemblies by it's string representation[^],
C# Reflection InvokeMember on existing instance[^],
Projects and DLL's: How to keep them managable?[^],
Dynamically Load User Controls[^],
code generating using CodeDom[^],
AppDomain refuses to load an assembly[^],
Create WPF Application that uses Reloadable Plugins...[^].

—SA


这篇关于访问驻留在插件dll中的自定义对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆