詳解C#動態載入程式集資訊

來源:互聯網
上載者:User
在設計模式的策略模式中,需要動態載入程式集資訊,本文通過一個簡單的執行個體,來講解動態載入Dll需要的知識點。下面跟著小編一起來看下吧

在設計模式的策略模式中,需要動態載入程式集資訊,本文通過一個簡單的執行個體,來講解動態載入Dll需要的知識點。

涉及知識點:

  • AssemblyName類,完整描述程式集的唯一標識, 用來表述一個程式集。

  • Assembly類,在System.Reflection命名空間下,表示一個程式集,它是一個可重用、無版本衝突並且可自我描述的通用語言執行平台應用程式建置組塊。

  • Module類 表述在模組上執行反射,表述一個程式集的模組資訊。

  • Type類,在System命名空間下,表示型別宣告:類類型、介面類型、數群組類型、實值型別、枚舉類型、型別參數、泛型型別定義,以及開放或封閉構造的泛型型別。

  • FieldInfo類,發現欄位屬性並提供對欄位中繼資料的訪問權。

  • MethodInfo類,探索方法的屬性並提供對方法中繼資料的訪問。

  • EventInfo類,發現事件的屬性並提供對事件中繼資料的訪問權。

  • ConstructorInfo類,發現類建構函式的屬性並提供對建構函式中繼資料的訪問權。

  • Activator類,包含特定的方法,用以在本地或從遠程建立物件類型,或擷取對現有遠程對象的引用。此類不能被繼承。

  • BindingFlags類,指定控制綁定和由反射執行的成員和類型搜尋方法的標誌。在擷取方法時,第二個參數會用到

如所示:

具體代碼如下:


public partial class DllLoadForm : Form  {    public DllLoadForm()    {      InitializeComponent();    }    private void btnOpenFile_Click(object sender, EventArgs e)    {      OpenFileDialog ofd = new OpenFileDialog()      {        Multiselect=false,        Filter = "Dll Info|*.dll|All Files|*.*",InitialDirectory=AppDomain.CurrentDomain.BaseDirectory,        Title="Dll資訊",        Tag="請選擇"      };      if (ofd.ShowDialog() == DialogResult.OK) {        this.txtDllFile.Text = ofd.FileName;      }    }    private void btnLoadDll_Click(object sender, EventArgs e)    {      if (string.IsNullOrEmpty(this.txtDllFile.Text.Trim())) {        MessageBox.Show("請選擇dll檔案");        return;      }      LoadDllInfo(this.txtDllFile.Text);    }    /// <summary>    /// 動態載入Dll    /// </summary>    /// <param name="dllPath">需要載入的Dll的路徑</param>    public void LoadDllInfo(string dllPath)    {      if (File.Exists(dllPath))      {        TreeNodeCollection tvNodes = tvDllInfo.Nodes;        tvNodes.Clear();        tvNodes.Add("DllInfo");        AssemblyName dllAssemblyName = AssemblyName.GetAssemblyName(dllPath);        Assembly dllAssembly = Assembly.Load(dllAssemblyName);        Module[] modules = dllAssembly.GetModules();//擷取作為程式集一部分的所有模組資訊        Type[] types = dllAssembly.GetTypes();//擷取程式集中定義的所有類型        AssemblyName[] referrenceAsseblies = dllAssembly.GetReferencedAssemblies();//擷取程式集引用的程式集資訊        tvNodes[0].Nodes.Add("基本資料");        string dllFullName = dllAssembly.FullName;        bool isGlobalAsseblyCache = dllAssembly.GlobalAssemblyCache;//是否從全域程式集載入        bool isFullTrusted = dllAssembly.IsFullyTrusted;//是否已完全信任方式載入的        Module manifestModule = dllAssembly.ManifestModule;//擷取清單模組        bool isReflectionOnly = dllAssembly.ReflectionOnly;//是否載入到只反射模組中        //更新到節點        tvNodes[0].Nodes[0].Nodes.Add(string.Format("全路徑:{0}", dllFullName));        tvNodes[0].Nodes[0].Nodes.Add(string.Format("是否全域程式集:{0}", isGlobalAsseblyCache));        tvNodes[0].Nodes[0].Nodes.Add(string.Format("是否全信任:{0}", isFullTrusted));        tvNodes[0].Nodes[0].Nodes.Add(string.Format("是否只反射:{0}", isReflectionOnly));        tvNodes[0].Nodes[0].Nodes.Add(string.Format("清單模組:{0}", manifestModule.Name));        IEnumerable<Type> exportedTypes = dllAssembly.ExportedTypes;//公用類型集合        tvNodes[0].Nodes.Add("模組資訊");        int i = 0;        foreach (var module in modules)        {          FieldInfo[] fields = module.GetFields();//返回模組中定義的全域欄位          MethodInfo[] methods = module.GetMethods();//返回模組中定義的全域方法          Type[] mtypes = module.GetTypes();//返回模組中定義的類型集合          bool isResource = module.IsResource();//指示此模組是否是資源          int mdStreamVersion = module.MDStreamVersion;//擷取來源資料流的版本          Guid versionId = module.ModuleVersionId;//擷取模組的版本ID          string moduleName = module.Name;//擷取模組的名稱,去除路徑的          int metadataToken = module.MetadataToken;          string scopeName = module.ScopeName;          tvNodes[0].Nodes[1].Nodes.Add(string.Format("模組:{0}", moduleName));          tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("資料流版本:{0}", mdStreamVersion));          tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("是否資源:{0}", isResource));          tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("版本ID:{0}", versionId));          tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("MetaData:{0}", metadataToken));          tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("ScopeName:{0}", scopeName));          tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(GetNodes<FieldInfo>(fields, "公用欄位"));          tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(GetNodes<MethodInfo>(methods, "Mehods"));          //tvNodes[0].Nodes[1].Nodes[i].Nodes.Add(string.Format("Types:{0}", string.Join(",", mtypes.Select(p => p.Name))));          i++;        }        tvNodes[0].Nodes.Add("類型資訊");        i = 0;        foreach (var type in types)        {          TypeAttributes typeAttributes = type.Attributes;//與Type關聯的屬性          string typeFullName = type.FullName;//擷取類型的完全限定名稱          FieldInfo[] typeFields = type.GetFields();//擷取所有的公用欄位          EventInfo[] typeEvents = type.GetEvents();//擷取所有的 公用事件          Type[] typeInterfaces = type.GetInterfaces();//擷取所有的公用介面          MemberInfo[] typeMembers = type.GetMembers();//擷取所有的公用成員          MethodInfo[] typeMethods = type.GetMethods();//擷取所有的公用方法          TypeInfo typeInfo = type.GetTypeInfo();//返回指定類型的表述形式          string nameSpace = type.Namespace; //指定類型的命名空間          string typeName = type.Name;//擷取當前成員的名稱          ConstructorInfo[] typeConstructors = type.GetConstructors();//類型的建構函式          tvNodes[0].Nodes[2].Nodes.Add(string.Format("類型:{0}", typeName));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("全名稱:{0}", typeFullName));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("制定類型名稱:{0}", typeInfo.Name));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("命名空間:{0}", nameSpace));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("介面:{0}", string.Join(",", typeInterfaces.Select(p => p.Name))));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<FieldInfo>(typeFields, "公用欄位"));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<ConstructorInfo>(typeConstructors, "建構函式"));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<EventInfo>(typeEvents, "事件"));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<MemberInfo>(typeMembers, "成員Member"));          tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(GetNodes<MethodInfo>(typeMethods, "公用方法"));          i++;        }      }    }    /// <summary>    /// 通過類型擷取節點    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="lstInfos"></param>    /// <param name="name"></param>    /// <returns></returns>    public TreeNode GetNodes<T>(T[] lstInfos, string name) where T : MemberInfo    {      TreeNode tNode = new TreeNode(name);      foreach (var t in lstInfos)      {        tNode.Nodes.Add(t.Name);      }      return tNode;    }    /// <summary>    /// 調用靜態方法的例子    /// </summary>    /// <param name="sender"></param>    /// <param name="e"></param>    private void btnCallStaticByReflection_Click(object sender, EventArgs e)    {      AssemblyName assemblyName = AssemblyName.GetAssemblyName("TestAssembly.exe");      Assembly assembly = Assembly.Load(assemblyName);      Type t = assembly.GetType("TestAssembly.Program", true, true);      //object o= Activator.CreateInstance(t, false);      MethodInfo methodInfo = t.GetMethod("Main",BindingFlags.Static|BindingFlags.Public);      methodInfo.Invoke(null,new string[][] { new string[] { "g" } });    }    /// <summary>    /// 調用非靜態方法的例子    /// </summary>    /// <param name="sender"></param>    /// <param name="e"></param>    private void btnCallFunctionByReflection_Click(object sender, EventArgs e)    {      AssemblyName assemblyName = AssemblyName.GetAssemblyName("TestAssembly.exe");//此處是相對路徑      Assembly assembly = Assembly.Load(assemblyName);      Type t = assembly.GetType("TestAssembly.Program", true, true);      object o = Activator.CreateInstance(t, false);      MethodInfo methodInfo = t.GetMethod("TestAssembly", BindingFlags.Instance|BindingFlags.Public);      object tmp= methodInfo.Invoke(o,null);      MessageBox.Show(tmp.ToString());    }  }

動態載入和反射調用的功能還有很多,不能一一列舉,只能在以後的工作中用到時再加以研究。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.