zoukankan      html  css  js  c++  java
  • 程序集加载与反射

    在可扩展应用程序中,将程序集加载到应用程序域主要用以下方法:

    Assembly的Load方法和LoadFrom方法。LoadFrom可以加载指定路径名或者URL的程序集。如果只是分析程序集的元数据,并不执行包含在程序集中的代码,那么可以用Assembly的ReflectionOnlyLoadFrom方法来加载程序集,效率更高。

         CLR不支持卸载单个程序集,如果希望卸载一个程序集,就必须卸载包含该程序集的整个应用程序域。

         应用程序一般很少使用反射类型,在需要加载某个特定的类型或程序集以执行任务时会用到。反射虽然功能强大,但也有缺点:

         1、反射在编译时不提供类型安全。因为反射使用了大量字符串,我们在编译时就失去了类型安全。

         2、反射的速度慢。使用反射时,类型及其成员的名称在编译时还不知道,我们需要在运行时通过使用字符串名称来标识每个类型及成员以发现他们。这意味着反射要不断的扫描程序集的整个元数据,执行System.Reflection命名空间中的类型的字符串搜索。

         如果在编写的应用程序需要动态的发现和构建类型,可以遵循以下方法:

         1、让类型派生自一个编译时已经确定的基础类型。然后在运行时构建一个该派生类型的实例,并将其引用存放在一个声明类型为其基础类型的变量中(可以进行类型转换),最后调用基础类型中定义的虚方法。(虚继承方法)

         2、让类型实现一个编译时已经确定的接口类型。然后在运行时构建一个该类型的实例,并将其引用存放在一个声明类型为其接口类型的变量中,最后调用接口类型中的方法。(接口实现方法)

         在使用时,最好将接口类型或者基础类型定义在自己的程序集中,以减少版本控制问题。一般情况下,还是建议使用接口方法,因为它允许开发人员选择自己的基类。

         发现类型的方法:Assembly的GetExportedTypes()函数

        获取类型的方法:GetTpye()

         创建类型实例:

         1、System.Activator的CreateInstance方法(常用)。参数为Type对象引用或者字符串,比较常用。

         2、System.Activator的CreateInstanceFrom方法。

         3、System.AppDomain的一些方法。与其他不同这是一些实例方法。

         4、System.Typede InvokeMemeber实例方法(常用)。通过使用一个Type对象的引用,可以调用他的InvokeMember方法。该方法会根据我们所传递的参数查找匹配的构造器,然后构建类型实例。类型实例总是被创建在当前方法调用所处的应用程序域中。InvokeMember会返回新创建的对象的调用。

         5、System.Reflection.ConstructorInfo的Invoke实例方法。

    以上方法可以创建出数组和委托之外的所有类型的实例。如果创建数组实例使用Array的静态方法CreateInstance。如果创建委托实例,使用Delegate的静态方法CreateDelegate。

     设计插件程序的步骤:

         1、创建一个定义了一个接口的“宿主SDK”程序集,该接口的方法用作宿主应用程序和插件组件之间的通信机制。他会被双方调用。因此一点确定了接口定义,就可以给这个程序集一个强命名,进行发行。发行后不要随意改变接口。如果对程序集进行了修改,可能需要使用一个发行策略文件来部署程序集。

         2、创建插件程序集,在此程序集中引用“宿主SDK”程序集中的类型。插件开发人员可以定义自己的类型并生成新的程序集。

         3、创建应用程序集。该程序集中也调用了“宿主SDK”程序集。

    在实际编程中,我们肯定会在插件所属的应用程序域内创建插件,并获取应用程序域的安全策略和配置设置。如果希望将插件从内存中移除,可以卸载该应用程序域。为了跨应用程序域边界进行通信,可以让插件派生自MashalByRefObject或者宿主应用程序定义自己的派生自MashalByRefObject的内部类型。

         使用反射发现并调用类型成员

         FCL包含了一个System.Reflection.MemberInfo的抽象基类,他封装了一组对所有类型成员通用的属性。如下图:

         在上面的层次中,并没有命名空间,他只是类型的而一个简单的语法集。如果希望列出命名空间,则需要调用类型的NameSpace属性。

         筛选返回成员的类型:BindingFlages

         获取类型所继承的接口:Type的FindInterface,GetInterface等方法。

         获取针对某个特定接口的对象:GetInterfaceMap

     

     

  • 相关阅读:
    grpc(五)
    go的代码库
    grpc(四)
    grpc(三)
    grpc(二)
    grpc(一)
    java的泛型
    如何学习编程语言
    老男孩K8S集群部署(二)
    VMware虚拟机状态正常,但SecureCRT连接时显示超时的解决方法
  • 原文地址:https://www.cnblogs.com/jyz/p/1290674.html
Copyright © 2011-2022 走看看