C# Detailed Explanation: Program Domain, Assembly, Module, Type, Reflection

Summarize:

">>>": Represents
the process containing >>> application domain AppDomain >>> assembly Assembly >>> module Module >>> type Type >>> members (methods, attributes, etc.)

1. Assembly Assembly

As shown in the figure, assume that there are multiple projects created in a solution:
(1) SuperControl: *main project to be started*
(2) ClassLibrary1: a custom class library that the main project needs to reference
(3) WindowsFormsApplication1: has nothing to do with the main project , there is no reference relationship
(4) Other DLL assemblies of the system referenced in the main project: For example,
after the System.Windows.Forms program starts running, an application domain will be created, which contains multiple assemblies, there are (1) 2) (4).
Each assembly can be understood as a separate project.

Use Assembly.GetExecutingAssembly() to get the assembly of the currently executing code, which can be understood as getting the current main project SuperControl. Use AppDomain.CurrentDomain.GetAssemblies() to get all the assemblies used in the current application domain. As shown below.

Supplement:
If the class library ClassLibrary1 is referenced in the running project SuperControl, the namespace using ClassLibrary1 is also referenced. But the actual code does not use anything in the ClassLibrary1 project. Using AppDomain.CurrentDomain.GetAssemblies() will not get the assembly named ClassLibrary1

2. Module Module

Take the assembly SuperControl as an example, which contains only one executable program SuperControl.exe.

3. Type Type

1. It is the class class, the structure struct, the enumeration enum, etc., all belong to the type Type.
2. If you use reflection, you need to get the specific type Type. Having the type Type means having all the information inside the class, and in the future, a new instance can be dynamically generated arbitrarily, or the data of the original instance can be dynamically changed.
3. If you want to obtain the classes defined in a certain project (that is, assembly assembly), you can use assembly assembly or module to obtain it, because they are almost one thing, and the main thing in a single assembly assembly is that. exe or .dll modules. Assembly Assembly >>> Module Module.
example:

 Assembly assembly = Assembly.GetExecutingAssembly();//获取当前项目程序集
            Type[] types = assembly.GetTypes();

 Assembly assembly = Assembly.GetExecutingAssembly();//获取当前项目程序集
       Module module = assembly.GetModule("SuperControl.exe");//获取里面的模块
            types = module.GetTypes();//获取里面所有的类型

4. Reflection: Dynamically generate an instance of the class name SubForm in the project SuperControl

//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);

5. Reflection case

The program uses the CreateControl() method to dynamically generate the required controls according to the user's choice: FlowLayoutPanel, Button, Label

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;

namespace SuperControl
{
    public partial class SubForm : DockContent
    {
        public SubForm()
        {
            InitializeComponent();

            this.ContextMenuStrip = contextMenuStrip1;
        }




        private void layoutPanelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateControl(typeof(FlowLayoutPanel), "fpanel");
        }

        private void buttonToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateControl(typeof(Button), "btn");
        }

        private void labelToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateControl(typeof(Label), "text");
        }

        public void obj_MouseDown(object sender, MouseEventArgs e)
        {
            MoveControl(sender as Control, e);
        }

        public void CreateControl(Type tp, string text)
        {
            // object obj = Assembly.GetExecutingAssembly().CreateInstance(tp.FullName); //不能用这个,因为该类型不是在当前程序集里                
             
            //方法一、
            object obj = Activator.CreateInstance(tp); //这个可以,应该是自动获取了必要的信息

            //方法二、
       //object obj =                 
      //AppDomain.CurrentDomain.CreateInstanceAndUnwrap("System.Windows.Forms,             
     //Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", tp.FullName);


            tp.GetProperty("Text").SetValue(obj, text); //设置Text
            tp.GetEvent("MouseDown").AddEventHandler(obj, new MouseEventHandler(obj_MouseDown)); //注册事件
            Point p = PointToClient(new Point(Control.MousePosition.X - 20, Control.MousePosition.Y - 10));
            tp.GetProperty("Location").SetValue(obj, p); //设置显示位置
            if (tp == typeof(FlowLayoutPanel))
            {
                tp.GetProperty("BorderStyle").SetValue(obj, BorderStyle.FixedSingle); //设置控件边框

            }
            this.Controls.Add(obj as Control); //将生成的控件添加到界面
        }






        #region 控件移动API


        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        public static extern bool ReleaseCapture();

        private void MoveControl(Control sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && e.Clicks == 1)
            {
                ReleaseCapture();
                SendMessage(sender.Handle, 161, 2, 0);
                SendMessage(sender.Handle, 0x0202, 0, 0);
            }
            else
            {
                //添加双击或右击代码……
            }
        }


        #endregion


    }
}

Guess you like

Origin blog.csdn.net/stephon_100/article/details/128152503