C#中的程序集和反射介绍
什么是程序集?
1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合。
2.程序集是组件复用,以及实施安全策略和版本策略的最小单位。
3.程序集是包含一个或者多个类型定义文件和资源文件的集合。在程序集包含的所有文件中,有一个文件用于保存清单。(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件)。
4、在编译应用程序中,所创建的CIL代码存储在一个程序集中,程序集包括可执行的应用程序文件(.exe扩展名文件)和其他应用程序使用的库(.dll扩展名文件)。
作为一个单元进行版本控制和部署的一个或多个文件的集合。程序集是.NETFramework 应用程序的主要构造块。所有托管类型和资源都包含在某个程序集内,并被标记为只能在该程序集的内部访问,或者被标记为可以从其他程序集中的代码访问。程序集在安全方面也起着重要作用。代码访问安全系统使用程序集信息来确定为程序集中的代码授予的权限集。
程序集是.NET Framework编程的基本组成部分。(此上是在百度百科的定义)
简单的说,net中的dll和exe文件都是程序集
程序集包含资源文件,类型元数据(描述在代码中定义的每一类型和成员,二进制形式)、IL代码(这些都被装在exe或dll中),每个程序集都有自己的名称、版本等信息。这些信息可以通过AssemblyInfo.cs文件来自己定义。
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AssemblyDemo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssemblyDemo")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("e7da9959-0c97-444c-aa40-6d9bbf728068")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 内部版本号
// 修订号
//
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
AssemblyInfo.cs
使用程序集的优点:
程序只需要应用必要的程序集,减少了编码量(例如log4net.dll),程序的尺寸 。
可以在程序集中封装一些代码,提供必要的接口,供引用该程序集的项目使用。
反射
提到程序集,就不得不说反射。反射就是动态获取程序集中的元数据(提供程序集的类型信息)的功能。也就是动态获取程序集中的元数据来操作类型的。比如咱们使用的vs中的智能提示,就是通过反射获取类的方法、属性的。
Type类是实现反射的一个很重要的类,通过它我们可以获取类中的所有信息包括方法、属性等。可以动态调用类的属性机及方法。
Type是对类的描述。
一个简单的例子新建一个类库MyAssembly添加Person类,生成:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyAssembly
{
public class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
private string gender;
public string Gender
{
get { return gender; }
set { gender = value; }
}
public Person(string name, int age, string gender)
{
this.name = name;
this.age = age;
this.gender = gender;
}
public void SayHi()
{
Console.WriteLine("大家好,我是{0},今年{1}岁了。",this.name,this.age);
}
}
}
新建一个控制台项目AssemblyDemo,将MyAssembly.dll复制到控制台bin/debug下,接下来通过动态加载程序集MyAssembly.dll获取该程序集下person类的属性和方法。代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
namespace AssemblyDemo
{
class Program
{
static void Main(string[] args)
{
//通过反射动态调用另一个程序集中的方法
//1加载程序集
string path = AppDomain.CurrentDomain.BaseDirectory;//获取当前.exe执行文件的路径
path = Path.Combine(path, "MyAssembly.dll");//拼接程序集的路径
Assembly assembly = Assembly.LoadFile(path);
//2创建Person类的对象
Type type = assembly.GetType("MyAssembly.Person");
object o = Activator.CreateInstance(type,"wolf",22,"未知");//实例化
//3获取方法的类型
MethodInfo methodInfo = type.GetMethod("SayHi");
//4反射调用方法
methodInfo.Invoke(o, null);
Console.Read();
}
}
}
结果:
未完待续。。。。。