项目开发的过程中,调试使用的可能是最多的操作。任何代码写出来都需要经过调试和整合,以此扩展和提升程序的稳定性和可靠性。谈到.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这两个特性,方便大家理解友元程序集这一特性。这篇文章希望对大家有所帮助,还是那句话,需者自取,也虚心接受吐槽。知识在于分享,更在于每一个人的思考。

DotNet友元程序集解析的更多相关文章

  1. InternalsVisibleToAttribute——把internal成员暴露给指定的友元程序集

    友元程序集简介 我们知道一个类中被定义为internal的成员(包括类型.方法.属性.变量.事件)是只能在同一个程序集中被访问到的(当然了,我这里说的是正常的方式,不包括通过反射来访问).这个规则在. ...

  2. c# 友元程序集

    在团队开发中,如果一个程序集中要调用另外一个程序集,但是要被调用的那个程序集又不想用public来公开自己的类, 那么怎么办,就是用最后一种internal来用来做类的可见性了. 下面来看一个简单例子 ...

  3. DotNet加密方式解析--散列加密

    没时间扯淡类,赶紧上车吧. 在现代社会中,信息安全对于每一个人都是至关重要的,例如我们的银行账户安全.支付宝和微信账户安全.以及邮箱等等,说到信息安全,那就必须得提到加密技术,至于加密的一些相关概念, ...

  4. DotNet加密方式解析--对称加密

    离过年又近了一天,回家已是近在咫尺,有人欢喜有人愁,因为过几天就得经历每年一度的装逼大戏,亲戚朋友加同学的各方显摆,所以得靠一剂年终奖来装饰一个安稳的年,在这里我想起了一个题目“论装逼的技术性和重要性 ...

  5. DotNet加密方式解析--数字签名

    马上就要过年回村里了,村里没有wifi,没有4G,没有流量,更加重要的是过几天电脑就得卖掉换车票了,得赶紧写几篇博客. 数据安全的相关技术在现在愈来愈变得重要,因为人们对于自身的信息都有一种保护的欲望 ...

  6. DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱.不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬.(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...).已经上班两天了,公司大部分人还在休假,而我早已上班, ...

  7. 【DotNet加密方式解析】-- 好文收藏

    By -- 彭泽 一. DotNet加密方式解析--散列加密 笔记: 散列加密种类: 1.MD5  128位 2.SHA-1  160位 3.SHA-256  256位 4.SHA-384  384位 ...

  8. 8.C#友元程序集----可访问性相关

    在一个团队或者公司中,一个人开发出来的程序集中的类的可见性有public,private和internal, public:对所有程序集可见,就是说如果拿到程序集.DLL文件,那么类就被公开了. pr ...

  9. 如何:创建签名的友元程序集(C# 和 Visual Basic)

    如何:创建签名的友元程序集(C# 和 Visual Basic) Visual Studio 2013    本示例演示了如何将友元程序集和具有强名称的程序集一起使用. 这两种程序集必须都使用强名称. ...

随机推荐

  1. nmp install 异常

    由于网络的原因,需要多试几次才可以的: -g参数 不会安装在当前目录的:

  2. Word常用实用知识1

    Word常用实用知识1 纯手打,可能有错别字,使用的版本是office Word 2013 转载请注明出处,谢谢. 快速输入日期(含格式) [插入]--[日期]   快速输入日期和时间(快捷键) 快速 ...

  3. mvc文件上传支持批量上传,拖拽以及预览,文件内容校验等

    使用bootstrap-fileinput 使用方式: 1.nuget:Install-Package bootstrap-fileinput 2.语言本地化{下载fileinput_locale_z ...

  4. Go并发编程实践

    前言 并发编程一直是Golang区别与其他语言的很大优势,也是实际工作场景中经常遇到的.近日笔者在组内分享了我们常见的并发场景,及代码示例,以期望大家能在遇到相同场景下,能快速的想到解决方案,或者是拿 ...

  5. 三分钟解读springmvc依赖

    长期以来都在写SSM框架的项目,却未能深入理解框架的搭建原理,而只是浅薄的理解前辈的架构,然后不断套用,项目做过几个,但框架的内涵却没有把握.小编打算今天从SpringMVC的依赖分析做起,一步步进行 ...

  6. arm交叉编译器科普

    交叉编译工具链的命名规则为:arch [-vendor] [-os] [-(gnu)eabi] arch - 体系架构,如ARM,MIPS vendor - 工具链提供商 os - 目标操作系统 ea ...

  7. php下安装动态扩展库的相关事项

    php下安装动态扩展库的相关事项 我下载的Apache版本为2.4,PHP版本为7.0. 将Apache与PHP集成配置好后(PHP安装目录为:G:\computer\web\php7,apache安 ...

  8. 【Java】Objects 源码学习

    2017-02-10 by 安静的下雪天  http://www.cnblogs.com/quiet-snowy-day/p/6387321.html    本篇概要 Objects 与 Object ...

  9. C#操作XML方式

    前言 前一篇XML读取,现在咱们继续XML操作相关 C#中也有三种操作(增.删.改.查)XML文件方法如下: 使用 XmlDocument(DOM模式) 使用 XmlTextWriter(流模式) 使 ...

  10. redis集群原理

    redis是单线程,但是一般的作为缓存使用的话,redis足够了,因为它的读写速度太快了.   官方的一个简单测试: 测试完成了50个并发执行100000个请求. 设置和获取的值是一个256字节字符串 ...