好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C# 动态加载程序集信息

 在设计模式的策略模式中,需要动态加载程序集信息,本文通过一个简单的实例,来讲解动态加载dll需要的知识点。

涉及知识点:

assemblyname类,完整描述程序集的唯一标识, 用来表述一个程序集。 assembly类,在system.reflection命名空间下,表示一个程序集,它是一个可重用、无版本冲突并且可自我描述的公共语言运行时应用程序构建基块。 module类 表述在模块上执行反射,表述一个程序集的模块信息。 type类,在system命名空间下,表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。 fieldinfo类,发现字段属性并提供对字段元数据的访问权。 methodinfo类,发现方法的属性并提供对方法元数据的访问。 eventinfo类,发现事件的属性并提供对事件元数据的访问权。 constructorinfo类,发现类构造函数的属性并提供对构造函数元数据的访问权。 activator类,包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。此类不能被继承。 bindingflags类,指定控制绑定和由反射执行的成员和类型搜索方法的标志。在获取方法时,第二个参数会用到

如下图所示:

具体代码如下:

?

public partial class dllloadform : form

   {

     public dllloadform()

     {

       initializecomponent();

     }

     private void btnopenfile_click( object sender, eventargs e)

     {

       openfiledialog ofd = new openfiledialog()

       {

         multiselect= false ,

         filter = "dll info|*.dll|all files|*.*" ,

initialdirectory=appdomain.currentdomain.basedirectory,

         title= "dll信息" ,

         tag= "请选择"

       };

       if (ofd.showdialog() == dialogresult.ok) {

         this .txtdllfile.text = ofd.filename;

       }

     }

     private void btnloaddll_click( object sender, eventargs e)

     {

       if ( string .isnullorempty( this .txtdllfile.text.trim())) {

         messagebox.show( "请选择dll文件" );

         return ;

       }

       loaddllinfo( this .txtdllfile.text);

     }

     /// <summary>

     /// 动态加载dll

     /// </summary>

     /// <param name="dllpath">需要加载的dll的路径</param>

     public void loaddllinfo( string dllpath)

     {

       if (file.exists(dllpath))

       {

         treenodecollection tvnodes = tvdllinfo.nodes;

         tvnodes.clear();

         tvnodes.add( "dllinfo" );

         assemblyname dllassemblyname = assemblyname.getassemblyname(dllpath);

         assembly dllassembly = assembly.load(dllassemblyname);

         module[] modules = dllassembly.getmodules(); //获取作为程序集一部分的所有模块信息

         type[] types = dllassembly.gettypes(); //获取程序集中定义的所有类型

         assemblyname[] referrenceasseblies = dllassembly.getreferencedassemblies(); //获取程序集引用的程序集信息

         tvnodes[0].nodes.add( "基本信息" );

         string dllfullname = dllassembly.fullname;

         bool isglobalasseblycache = dllassembly.globalassemblycache; //是否从全局程序集加载

         bool isfulltrusted = dllassembly.isfullytrusted; //是否已完全信任方式加载的

         module manifestmodule = dllassembly.manifestmodule; //获取清单模块

         bool isreflectiononly = dllassembly.reflectiononly; //是否加载到只反射模块中

         //更新到节点

         tvnodes[0].nodes[0].nodes.add( string .format( "全路径:{0}" , dllfullname));

         tvnodes[0].nodes[0].nodes.add( string .format( "是否全局程序集:{0}" , isglobalasseblycache));

         tvnodes[0].nodes[0].nodes.add( string .format( "是否全信任:{0}" , isfulltrusted));

         tvnodes[0].nodes[0].nodes.add( string .format( "是否只反射:{0}" , isreflectiononly));

         tvnodes[0].nodes[0].nodes.add( string .format( "清单模块:{0}" , manifestmodule.name));

         ienumerable<type> exportedtypes = dllassembly.exportedtypes; //公共类型集合

         tvnodes[0].nodes.add( "模块信息" );

         int i = 0;

         foreach (var module in modules)

         {

           fieldinfo[] fields = module.getfields(); //返回模块中定义的全局字段

           methodinfo[] methods = module.getmethods(); //返回模块中定义的全局方法

           type[] mtypes = module.gettypes(); //返回模块中定义的类型集合

           bool isresource = module.isresource(); //指示此模块是否是资源

           int mdstreamversion = module.mdstreamversion; //获取源数据流的版本

           guid versionid = module.moduleversionid; //获取模块的版本id

           string modulename = module.name; //获取模块的名称,去除路径的

           int metadatatoken = module.metadatatoken;

           string scopename = module.scopename;

           tvnodes[0].nodes[1].nodes.add( string .format( "模块:{0}" , modulename));

           tvnodes[0].nodes[1].nodes[i].nodes.add( string .format( "数据流版本:{0}" , mdstreamversion));

           tvnodes[0].nodes[1].nodes[i].nodes.add( string .format( "是否资源:{0}" , isresource));

           tvnodes[0].nodes[1].nodes[i].nodes.add( string .format( "版本id:{0}" , versionid));

           tvnodes[0].nodes[1].nodes[i].nodes.add( string .format( "metadata:{0}" , metadatatoken));

           tvnodes[0].nodes[1].nodes[i].nodes.add( string .format( "scopename:{0}" , scopename));

           tvnodes[0].nodes[1].nodes[i].nodes.add(getnodes<fieldinfo>(fields, "公共字段" ));

           tvnodes[0].nodes[1].nodes[i].nodes.add(getnodes<methodinfo>(methods, "mehods" ));

           //tvnodes[0].nodes[1].nodes[i].nodes.add(string.format("types:{0}", string.join(",", mtypes.select(p => p.name))));

           i++;

         }

         tvnodes[0].nodes.add( "类型信息" );

         i = 0;

         foreach (var type in types)

         {

           typeattributes typeattributes = type.attributes; //与type关联的属性

           string typefullname = type.fullname; //获取类型的完全限定名称

           fieldinfo[] typefields = type.getfields(); //获取所有的公共字段

           eventinfo[] typeevents = type.getevents(); //获取所有的 公共事件

           type[] typeinterfaces = type.getinterfaces(); //获取所有的公共接口

           memberinfo[] typemembers = type.getmembers(); //获取所有的公共成员

           methodinfo[] typemethods = type.getmethods(); //获取所有的公共方法

           typeinfo typeinfo = type.gettypeinfo(); //返回指定类型的表述形式

           string namespace = type. namespace ; //指定类型的命名空间

           string typename = type.name; //获取当前成员的名称

           constructorinfo[] typeconstructors = type.getconstructors(); //类型的构造函数

           tvnodes[0].nodes[2].nodes.add( string .format( "类型:{0}" , typename));

           tvnodes[0].nodes[2].nodes[i].nodes.add( string .format( "全名称:{0}" , typefullname));

           tvnodes[0].nodes[2].nodes[i].nodes.add( string .format( "制定类型名称:{0}" , typeinfo.name));

           tvnodes[0].nodes[2].nodes[i].nodes.add( string .format( "命名空间:{0}" , namespace ));

           tvnodes[0].nodes[2].nodes[i].nodes.add( string .format( "接口:{0}" , string .join( "," , typeinterfaces.select(p => p.name))));

           tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<fieldinfo>(typefields, "公共字段" ));

           tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<constructorinfo>(typeconstructors, "构造函数" ));

           tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<eventinfo>(typeevents, "事件" ));

           tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<memberinfo>(typemembers, "成员member" ));

           tvnodes[0].nodes[2].nodes[i].nodes.add(getnodes<methodinfo>(typemethods, "公共方法" ));

           i++;

         }

       }

     }

     /// <summary>

     /// 通过类型获取节点

     /// </summary>

     /// <typeparam name="t"></typeparam>

     /// <param name="lstinfos"></param>

     /// <param name="name"></param>

     /// <returns></returns>

     public treenode getnodes<t>(t[] lstinfos, string name) where t : memberinfo

     {

       treenode tnode = new treenode(name);

       foreach (var t in lstinfos)

       {

         tnode.nodes.add(t.name);

       }

       return tnode;

     }

     /// <summary>

     /// 调用静态方法的例子

     /// </summary>

     /// <param name="sender"></param>

     /// <param name="e"></param>

     private void btncallstaticbyreflection_click( object sender, eventargs e)

     {

       assemblyname assemblyname = assemblyname.getassemblyname( "testassembly.exe" );

       assembly assembly = assembly.load(assemblyname);

       type t = assembly.gettype( "testassembly.program" , true , true );

       //object o= activator.createinstance(t, false);

       methodinfo methodinfo = t.getmethod( "main" ,bindingflags. static |bindingflags. public );

       methodinfo.invoke( null , new string [][] { new string [] { "g" } });

     }

     /// <summary>

     /// 调用非静态方法的例子

     /// </summary>

     /// <param name="sender"></param>

     /// <param name="e"></param>

     private void btncallfunctionbyreflection_click( object sender, eventargs e)

     {

       assemblyname assemblyname = assemblyname.getassemblyname( "testassembly.exe" ); //此处是相对路径

       assembly assembly = assembly.load(assemblyname);

       type t = assembly.gettype( "testassembly.program" , true , true );

       object o = activator.createinstance(t, false );

       methodinfo methodinfo = t.getmethod( "testassembly" , bindingflags.instance|bindingflags. public );

       object tmp= methodinfo.invoke(o, null );

       messagebox.show(tmp.tostring());

     }

   }

动态加载和反射调用的功能还有很多,不能一一列举,只能在以后的工作中用到时再加以研究。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持服务器之家!

原文链接:http://www.cnblogs.com/hsiang/p/6505568.html

dy("nrwz");

查看更多关于C# 动态加载程序集信息的详细内容...

  阅读:43次