总结:
">>>":代表包含
进程>>>应用程序域AppDomain>>>程序集Assembly>>>模块Module>>>类型Type>>>成员(方法、属性等)
1、程序集Assembly
如图,假设一个解决方案里创建有多个项目:
(1)SuperControl:*要启动的主项目*
(2)ClassLibrary1:主项目需要引用的自定义的类库
(3)WindowsFormsApplication1:和主项目无关,没有引用关系
(4)主项目里引用的系统的其他DLL程序集:如System.Windows.Forms
程序开始运行后,就会建立一个应用程序域,其中包含多个程序集,有(1)(2)(4)。
每个程序集可以理解为一个单独的项目。
使用Assembly.GetExecutingAssembly()可以获取当前执行代码的程序集,可以理解为获取当前的主项目SuperControl。使用AppDomain.CurrentDomain.GetAssemblies()可以获取当前应用程序域中所有用到的程序集。如下图。
补充:
如果运行的项目SuperControl中引用了类库ClassLibrary1,也引用了命名空间using ClassLibrary1。但实际代码里没有用到ClassLibrary1项目中的任何东西,使用AppDomain.CurrentDomain.GetAssemblies()就不会获取到名为ClassLibrary1的程序集
2、模块Module
以程序集SuperControl为例,其中包含的模块只有一个SuperControl.exe的可执行程序。
3、类型Type
1、就是类class,结构体struct,枚举enum等,都是属于类型Type。
2、如果用到反射就需要拿到具体的类型Type。有了类型Type就等于有了这个类内部的所有信息,以后就可以任意的动态生成一个新的实例,或者动态改变原来实例的数据。
3、如果要获取某个项目(即程序集Assembly)里面定义的类,可以用程序集Assembly,也可以用Module来获取,因为它们近乎是一个东西,单个程序集Assembly里主要的东西就是那个.exe或者.dll模块。程序集Assembly>>>模块Module。
例:
Assembly assembly = Assembly.GetExecutingAssembly();//获取当前项目程序集
Type[] types = assembly.GetTypes();
Assembly assembly = Assembly.GetExecutingAssembly();//获取当前项目程序集
Module module = assembly.GetModule("SuperControl.exe");//获取里面的模块
types = module.GetTypes();//获取里面所有的类型
4、反射:动态生成项目SuperControl中类名为SubForm的实例
//Assembly assembly = //Assembly.LoadFrom(@"C:\Users\Administrator\Desktop\TEST\ControlMoveTEST\SuperControl\
//SuperControl\bin\Debug\SuperControl");
Assembly asy = Assembly.GetExecutingAssembly();
object obj = asy.CreateInstance("SuperControl.SubForm");//填类型全名,包括命名空间
//如果要操作其他的项目程序集里的内容,就获取别的项目的Assembly。
//(1)显示窗体方式1
((SubForm)obj).Show();//显示窗体
//(2)显示窗体方式2
Type typeInfo = asy.GetType("SuperControl.SubForm");//填类型全名,包括命名空间
MethodInfo minfo = typeInfo.GetMethod("Show",new Type[]{});//显示窗体1
minfo.Invoke(obj, null);//显示窗体2
//(3) 设置窗体的启动位置
typeInfo.GetProperty("StartPosition").SetValue(obj, FormStartPosition.CenterScreen);