zoukankan      html  css  js  c++  java
  • DotNet友元程序集解析

       项目开发的过程中,调试使用的可能是最多的操作。任何代码写出来都需要经过调试和整合,以此扩展和提升程序的稳定性和可靠性。谈到.NET的单元测试,在这里就得提提.NET的友元程序集这一特性,也借用.NET进行单元测试的一个较为好用的.NET属性,来讲解一下程序集、定制Attribute的相关知识。一些知识需要反复的去品味和反思,不要觉得你会了就不在意,等你在意的时候,你就有些力不从心的意思了。

       生活在于不停的折腾,只有经过磨练,才可知何时需要安分,何时需要挑战。

       毒鸡汤喝完了,来聊聊正事...

    一.程序集概述

      本文主要是谈论“友元程序集”的一些知识,既然是做一个解析,那么就应该把一些知识做一个展开来论述。在这里先谈谈程序集(有人觉得很了解,有人觉得完全不懂,情况不同,选择不同,需者自取吧),接下来我们具体的看看程序集这一特性。

      程序集是一个或多个模块/资源文件的逻辑分组,程序集是重用、安全性以及版本控制的最小单元。对于程序集的结构有如下图。

        对于程序集的组成就不一一做解析,在这里就单独谈谈元数据这一结构。元数据是一个二进制数据块,由一组数据表,元数据总是与包含IL代码的文件关联,元数据由几个表构成。元数据的作用有上图介绍。元数据的表有三个类别:定义表,引用表,清单表。对于这些表的结构在这里就不做介绍了,有兴趣的可以搜索一下,个人认为元数据这一结构应该好好的研究一下。

    二.定制Attribute概述

       上面的论述中简单的介绍了程序集的结构和元数据,在这里简单的介绍一下定制Attribute这一.NET的特性。定制Attribute允许定义的信息应用于几乎每一个元数据表记录项,这种可扩展的元数据信息能在运行时查询,从而动态改变代码的执行方式。在C#种,为了将一个定制Attribute应用于一个目标元素,需要将Attribute放置于目标元素前面的一对方括号中。

       CLR允许将定制Attribute应用于可在文件的元数据中表示的几乎所有元素。定制Attribute主要应用于程序集、模块、类型、字段、方法、方法参数、方法返回值、属性、事件、泛型类型参数。attribute是类的一个实例,将一个attribute应用于一个目标元素时,语法类似于调用类的某个实例构造函数。定制Attribute的实例如下:

    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]

        上面代码取自InternalsVisibleToAttribute类中,该类是完成友元程序集特性的核心对象,下面会做一个具体的介绍。AttributeUsage需要接受一个AttributeTargets枚举类型的值作为参数,称之为定位参数,是强制性的,必须指定。AllowMultiple参数用于获取或设置一个布尔值,指示是否有多个实例指定的属性可以为单个程序元素指定。Inherited参数用于获取或设置一个布尔值,指示指定的属性是否可以继承由派生类和重写成员。

       定制Attribute可以应用于单个目标元素,定制Attribute的顺序是无关紧要的。在C#种,可将每个Attribute都封闭到一对方括号中,也可以在一对方括号中封闭多个以逗号分隔的Attribute。

       定制Attribute就是一个类的实例,它被序列化成驻留在元数据中的一个字节流,在运行时,可以对元数据中包含的字节进行反序列化,从而构造类的一个实例。

    三.友元程序集解析

       扯了半天,终于到讲解“友元程序集”这一个概念,“友元程序集”在.NET2中提出,使用InternalsVisibleToAttribute来实现这一特性,InternalsVisibleTo只能用于程序集,并且你可以在同一个程序集种应用多次。源程序集:包含这个属性的程序集。友元程序集能够看到源程序集的所有内部成员,类似于公有的。

       友元程序集实例介绍:

    //AssemblySource.DLL
    [assembly: InternalsVisibleTo(DotNetShare)]
    public class AssemblySource
    {
        public static void Share();
    }
    
    
    //DotNetShare.DLL
    public class DotNetShare
    {
        private static void Main()
        {
            AssemblySource.Share();
        }
    }

        AssemblySource.DLL和DotNetShare.DLL之间存在一种特殊的关系,但是这种关系只能单项操作。接下来看一下InternalsVisibleToAttribute的实现源码。InternalsVisibleToAttribute继承自Attribute类,该类指定通常仅在当前程序集中可见的类型对指定程序集可见。该类包含两个属性和一个方法。

       1.AssemblyName

    public string AssemblyName
        {
          [__DynamicallyInvokable] get
          {
            return this._assemblyName;
          }
        }

       该属性为一个只读属性,一个表示友元程序集名称的字符串。该属性用于获取友元程序集的名称,采用 internal 关键字标记的所有类型和类型成员对该程序集均为可见。

      2.InternalsVisibleToAttribute()

    public InternalsVisibleToAttribute(string assemblyName)
        {
          this._assemblyName = assemblyName;
        }

       该方法为一个构造函数,用指定的友元程序集的名称初始化 <see cref="T:System.Runtime.CompilerServices.InternalsVisibleToAttribute"/> 类的新实例。接收一个友元程序集的名称。

      对于友元程序集有一个约束,如果一个友元程序集是签名的,那么源程序集为了保证信任正确的代码,就需要指定友元程序集的公钥。

    四.总结

       对于本文主要是在介绍友元程序集这一特性,顺带介绍程序集和定制Attribute这两个特性,方便大家理解友元程序集这一特性。这篇文章希望对大家有所帮助,还是那句话,需者自取,也虚心接受吐槽。知识在于分享,更在于每一个人的思考。

  • 相关阅读:
    C语言基础---字符指针变量和字符数组的区别
    C语言基础---编写C语言代码过程中易忽略的点
    C语言简介---通过指针引用多维数组
    C语言基础---特殊的变量类型(结构体、枚举、共用体)
    C语言基础---指针简述
    C语言基础---C语言中的变量与内存空间的关系
    嵌入式开发中常用到的C语言库函数
    SVN使用---简介
    视频编解码相关基础知识(二)---H.264简介
    MybatisPlus MetaObjectHandler 配置
  • 原文地址:https://www.cnblogs.com/pengze0902/p/6539694.html
Copyright © 2011-2022 走看看