如何动态加载dll文件 [英] How to dynamically load dll file

查看:102
本文介绍了如何动态加载dll文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我整夜都在浏览示例,似乎找不到足够简单的例子来说明我在寻找什么.

我需要将dll动态添加到我的项目中,创建它的实例,然后调用它的方法.假设我具有以下方法的dll文件,但我不知道名称空间或类的名称.

I have been going through examples the whole night, cant seem to find anything simple enough to exmplain what I am looking for.

I need to dynamically add a dll to my project, create an instance of it, and invoke it''s methods. Let''s say I have the follwing dll file with the following method, but I do not know the namespace, or the name of the class.

public string Greeting(string Name)
{
   return "Hello " + Name;
}



我将如何将dll加载到程序集/应用程序域中,并在我的项目中创建dll中未知类的实例,并访问dll中的方法Greeting?

有人可以帮我吗?



How would I go about loading the dll into an assembly/app domain, and create an instance of the unknown class that is in the dll, in my project, and access the method Greeting that is within the dll?

Can anyone please help me?

推荐答案

简短的答案是:您需要使用System.Reflection.Assembly.LoadFrom(string fileName)从文件加载程序集.这是最简单的情况.您可以加载放置在CAG中的程序集,并使用LoadFrom方法中的其他Load.请参阅:
http://msdn.microsoft.com/en-us/library/system.reflection. assembly.aspx [^ ].

完成此操作后,您可以使用获取的对Assembly对象的引用,并使用Reflection查找要使用的一个或多个类,并最终使用ConstructorInfo.Invoke实例化一个或多个类,或使用MethodInfo.Invoke进行调用立即使用一些静态方法(显然,您不需要实例来调用静态类);同样,可以使用PropertyInfo及其getter或setter方法设置/获取静态属性值.您可以使用对上一步中获得的类的实例的引用来调用非静态方法/属性.请参阅:
http://msdn.microsoft.com/en-us/library/system.reflection. constructorinfo.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/system.reflection. methodinfo.aspx [ ^ ],
http://msdn.microsoft.com/en-us/library/system.reflection. propertyinfo.aspx [ ^ ].

为此类操作选择适当的模式需要一些思考.特别是,使用类或成员的名称非常糟糕,因为这是不支持的:如果您拼写错误或稍后更改名称,编译器将不会检测到错误.最安全的方法是定义一些可由主机应用程序和插件访问的插件接口,并搜索实现此接口的类.请查看此方法用于检查某些类或结构是否实现了某些接口:
http://msdn.microsoft.com/en-us/library/system.type. isassignablefrom.aspx [ ^ ].

使用方法System.Type.IsAssignableFrom时,应在接口类型上使用它:
Short answer is: you need to load the assembly from file using System.Reflection.Assembly.LoadFrom(string fileName). This is the simplest case. You can load assembly placed in CAG and use other Load of LoadFrom methods. Please see:
http://msdn.microsoft.com/en-us/library/system.reflection.assembly.aspx[^].

When this is done, you can use the obtained reference to the Assembly object and use Reflection to find one or more classes you want to use and ultimately use ConstructorInfo.Invoke to instantiate one or more classes, or use MethodInfo.Invoke to call some static method(s) immediately (apparently, you don''t need an instance to call a static class); the same way, you can use PropertyInfo and its getter or setter methods to set/get a static property value. You can call non-static methods/properties using the reference to the instance of the class obtained on the previous step. Please see:
http://msdn.microsoft.com/en-us/library/system.reflection.constructorinfo.aspx[^],
http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.aspx[^],
http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.aspx[^].

Selection of proper schema for such operations needs some thinking. In particular, it''s pretty bad to use names of the classes or members, because this is not supportable: the compiler won''t detect an error if you misspell such name or change it later. The safest approach is to define some plug-in interface accessible by both host application and the plug-in and search for the classes implementing this interface. Please see this method to be used to check is some class or structure implements some interface or not:
http://msdn.microsoft.com/en-us/library/system.type.isassignablefrom.aspx[^].

When you use the method System.Type.IsAssignableFrom, you should use it on the interface type:
System.Type type = //get from Reflection, from the assembly in question
if (typeof(IMyPlugin).IsAssignableFrom(type)
   //it means that type implements IMyPlugin



我通常会再走一步,以避免扫描所有可用的类型.我介绍了一个自定义的程序集级属性,该属性声明哪些类型实现了哪种接口—它节省了时间,并且消除了多个类/结构实现同一接口的问题,因此不清楚使用哪种接口.同时,应该在运行时验证此声明,但这在所有情况下都是不可避免的.

当您不想卸载和组装时,上述技术相当容易.这是不可能的,因此卸载任何内容的唯一方法是将程序集加载到单独的Application Domain中.这将迫使您穿越应用程序域"边界,这意味着使用IPC.我分析了这个问题,并在过去的回答中更详细地概述了该体系结构:
创建使用可重载插件的WPF应用程序... [^ ],
AppDomain拒绝加载程序集 [使用CodeDom生成代码 [创建使用可重载插件的WPF应用程序... [ ^ ],
动态加载用户控件 [在现有实例上的C#反射InvokeMember [项目和DLL:如何使其可管理? [ ^ ].

—SA



I usually make one more step to avoid scanning all available types. I introduce a custom assembly-level attribute which claims which types implement what interface — it saves time and eliminates the problem where several classes/structures implement the same interface, so it would not be clear which one to use. At the same time, this claim should be validated during run time, but this is unavoidable in all cases.

The above techniques are fairly easy as soon as you don''t want to unload and assembly. This is not possible, so the only way of unloading anything is loading the assembly in a separate Application Domain. It would force you to work through the Application Domain boundary, which means using IPC. I analyze this problem and overview the architecture in further detail in my past answers:
Create WPF Application that uses Reloadable Plugins...[^],
AppDomain refuses to load an assembly[^],
code generating using CodeDom[^],
Create WPF Application that uses Reloadable Plugins...[^],
Dynamically Load User Controls[^],
C# Reflection InvokeMember on existing instance[^] (invocation is explained in further detail here),
Projects and DLL''s: How to keep them managable?[^].

—SA


这篇关于如何动态加载dll文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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