灵活正确的实现.NET插件机制
。net 提供的反射(reflection)机制可以很方便的加载插件。本文提供一种方法,可以灵活的正确的载入所需的插件。
在。net中,一个完整的类型名称的格式如 "类型名, 程序集名".
例如:"system.configuration.namevaluesectionhandler, system, version=1.0.3300.0, culture=neutral, publickeytoken=b77a5c561934e089".
类型名为:system.configuration.namevaluesectionhandler,这是带名字空间的完整类型名。
你也可以使用该类型的fullname得到。
如:string typename = typeof(namevaluesectionhandler)。fullname;程序集名为:"system, version=1.0.3300.0, culture=neutral, publickeytoken=b77a5c561934e089",程序集名为system,系统为自动为其适配扩展名(如system.dll或system.exe);version、culture、publickeytoken为程序集的具体版本、文化背景、签名,没有特定要求,这些都可以省略。
我们可以根据类型的名称,来动态载入一个所需要的类型。如:
string typename = "system.configuration.namevaluesectionhandler, system";type t = type.gettype(typename);object obj = activator.createinstance(t);//或system.configuration.namevaluesectionhandler obj = (system.configuration.namevaluesectionhandler)activator.createinstance(t);
此时,obj 就是所需要的类型实例。
通常的插件,是需要实现一定的接口的类。因此,在载入插件之前,需要确定该插件类型是否是合适的。
比如,一个插件的接口为 iplugin,那么我们可以用如下方式来识别:
string interfacename = typeof(iplugin)。fullname;string typename = "muf.myplugin, myplugin";type t = type.gettype(typename);
if ( t == null!t.isclass!t.ispublic t.getinterface(interfacename) == null)(来源www.iocblog.net)
{ return null; // 不是所需要的插件}
总结上述代码,我们可以做出通用的加载插件的代码:
/**//// <summary> /// 动态装载并创建类型,该类型拥有指定接口/// </summary> /// <param name="classname">类型名称</param> /// <param name="interfacename">指定的接口名称</param> /// <param name="param">指定构造函数的参数(null或空的数组表示调用默认构造函数)</param> /// <returns>返回所创建的类型(null表示该类型无法创建或找不到)</returns> public static object loadobject(string classname, string interfacename, object[] param)
{ try { type t = type.gettype(classname);
if ( t == null!t.isclass!t.ispublic t.isabstract t.getinterface(interfacename) == null)
{ return null;}
object o = activator.createinstance(t, param);if( o == null )
{ return null;}
return o;} catch( exception ex )
{ return null;}
以后,我们就可以使用loadobject载入任何所需的插件。
插件一般放在配置文件中,并由程序读入:
配置文件举例(配置文件的使用参见我的相关随笔):
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configsections> <section name="channels" type="vmp.configuration.channelssectionhandler, communication" /> </configsections>
<channels> <channel channeltype="vmp.communication.tcpchannel, communication" tracefile="d:logchannel1.log" port="2020" maxconnections="300" buffersize="2048" /> </channels> </configuration>代码范例:
Tag: 插件
文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。