C# 動(dòng)態(tài)加載程序集信息
在設(shè)計(jì)模式的策略模式中,需要?jiǎng)討B(tài)加載程序集信息,本文通過一個(gè)簡單的實(shí)例,來講解動(dòng)態(tài)加載Dll需要的知識點(diǎn)。
涉及知識點(diǎn):
- AssemblyName類,完整描述程序集的唯一標(biāo)識, 用來表述一個(gè)程序集。
- Assembly類,在System.Reflection命名空間下,表示一個(gè)程序集,它是一個(gè)可重用、無版本沖突并且可自我描述的公共語言運(yùn)行時(shí)應(yīng)用程序構(gòu)建基塊。
- Module類 表述在模塊上執(zhí)行反射,表述一個(gè)程序集的模塊信息。
- Type類,在System命名空間下,表示類型聲明:類類型、接口類型、數(shù)組類型、值類型、枚舉類型、類型參數(shù)、泛型類型定義,以及開放或封閉構(gòu)造的泛型類型。
- FieldInfo類,發(fā)現(xiàn)字段屬性并提供對字段元數(shù)據(jù)的訪問權(quán)。
- MethodInfo類,發(fā)現(xiàn)方法的屬性并提供對方法元數(shù)據(jù)的訪問。
- EventInfo類,發(fā)現(xiàn)事件的屬性并提供對事件元數(shù)據(jù)的訪問權(quán)。
- ConstructorInfo類,發(fā)現(xiàn)類構(gòu)造函數(shù)的屬性并提供對構(gòu)造函數(shù)元數(shù)據(jù)的訪問權(quán)。
- Activator類,包含特定的方法,用以在本地或從遠(yuǎn)程創(chuàng)建對象類型,或獲取對現(xiàn)有遠(yuǎn)程對象的引用。此類不能被繼承。
- BindingFlags類,指定控制綁定和由反射執(zhí)行的成員和類型搜索方法的標(biāo)志。在獲取方法時(shí),第二個(gè)參數(shù)會用到
如下圖所示:
具體代碼如下:
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> /// 動(dòng)態(tài)加載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;//是否加載到只反射模塊中 //更新到節(jié)點(diǎn) 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;//獲取源數(shù)據(jù)流的版本 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("數(shù)據(jù)流版本:{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關(guān)聯(lián)的屬性 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;//獲取當(dāng)前成員的名稱 ConstructorInfo[] typeConstructors = type.GetConstructors();//類型的構(gòu)造函數(shù) 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, "構(gòu)造函數(shù)")); 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> /// 通過類型獲取節(jié)點(diǎn) /// </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> /// 調(diào)用靜態(tài)方法的例子 /// </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> /// 調(diào)用非靜態(tài)方法的例子 /// </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()); } }
動(dòng)態(tài)加載和反射調(diào)用的功能還有很多,不能一一列舉,只能在以后的工作中用到時(shí)再加以研究。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
silverlight實(shí)現(xiàn)圖片局部放大效果的方法
這篇文章主要介紹了silverlight實(shí)現(xiàn)圖片局部放大效果的方法,結(jié)合實(shí)例形式分析了silverlight針對圖片屬性的相關(guān)操作技巧,需要的朋友可以參考下2017-03-03解析C#編程的通用結(jié)構(gòu)和程序書寫格式規(guī)范
這篇文章主要介紹了C#編程的通用結(jié)構(gòu)和程序書寫格式規(guī)范,這里我們根據(jù)C#語言的開發(fā)方微軟給出的約定來作為編寫樣式參照,需要的朋友可以參考下2016-01-01c#不使用windows api函數(shù)打開我的電腦和獲取電腦驅(qū)動(dòng)器信息
這篇文章主要介紹了c#不使用windows api函數(shù)打開我的電腦和電腦驅(qū)動(dòng)器信息的方法,大家參考使用2013-12-12C#中實(shí)現(xiàn)可變參數(shù)實(shí)例
這篇文章主要介紹了C#中實(shí)現(xiàn)可變參數(shù)實(shí)例,本文演示使用params 實(shí)現(xiàn)可變數(shù)量的參數(shù),并且這些參數(shù)的類型可以不同,需要的朋友可以參考下2015-01-01WinForm DataGridView控件隔行變色的小例子
WinForm的DataGridView控件設(shè)置行的顏色2013-03-03