C# 動(dòng)態(tài)加載程序集信息
在設(shè)計(jì)模式的策略模式中,需要?jiǎng)討B(tài)加載程序集信息,本文通過(guò)一個(gè)簡(jiǎn)單的實(shí)例,來(lái)講解動(dòng)態(tài)加載Dll需要的知識(shí)點(diǎn)。
涉及知識(shí)點(diǎn):
- AssemblyName類(lèi),完整描述程序集的唯一標(biāo)識(shí), 用來(lái)表述一個(gè)程序集。
- Assembly類(lèi),在System.Reflection命名空間下,表示一個(gè)程序集,它是一個(gè)可重用、無(wú)版本沖突并且可自我描述的公共語(yǔ)言運(yùn)行時(shí)應(yīng)用程序構(gòu)建基塊。
- Module類(lèi) 表述在模塊上執(zhí)行反射,表述一個(gè)程序集的模塊信息。
- Type類(lèi),在System命名空間下,表示類(lèi)型聲明:類(lèi)類(lèi)型、接口類(lèi)型、數(shù)組類(lèi)型、值類(lèi)型、枚舉類(lèi)型、類(lèi)型參數(shù)、泛型類(lèi)型定義,以及開(kāi)放或封閉構(gòu)造的泛型類(lèi)型。
- FieldInfo類(lèi),發(fā)現(xiàn)字段屬性并提供對(duì)字段元數(shù)據(jù)的訪問(wèn)權(quán)。
- MethodInfo類(lèi),發(fā)現(xiàn)方法的屬性并提供對(duì)方法元數(shù)據(jù)的訪問(wèn)。
- EventInfo類(lèi),發(fā)現(xiàn)事件的屬性并提供對(duì)事件元數(shù)據(jù)的訪問(wèn)權(quán)。
- ConstructorInfo類(lèi),發(fā)現(xiàn)類(lèi)構(gòu)造函數(shù)的屬性并提供對(duì)構(gòu)造函數(shù)元數(shù)據(jù)的訪問(wèn)權(quán)。
- Activator類(lèi),包含特定的方法,用以在本地或從遠(yuǎn)程創(chuàng)建對(duì)象類(lèi)型,或獲取對(duì)現(xiàn)有遠(yuǎn)程對(duì)象的引用。此類(lèi)不能被繼承。
- BindingFlags類(lèi),指定控制綁定和由反射執(zhí)行的成員和類(lèi)型搜索方法的標(biāo)志。在獲取方法時(shí),第二個(gè)參數(shù)會(huì)用到
如下圖所示:
具體代碼如下:
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="請(qǐng)選擇"
};
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("請(qǐng)選擇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();//獲取程序集中定義的所有類(lèi)型
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;//公共類(lèi)型集合
tvNodes[0].Nodes.Add("模塊信息");
int i = 0;
foreach (var module in modules)
{
FieldInfo[] fields = module.GetFields();//返回模塊中定義的全局字段
MethodInfo[] methods = module.GetMethods();//返回模塊中定義的全局方法
Type[] mtypes = module.GetTypes();//返回模塊中定義的類(lèi)型集合
bool isResource = module.IsResource();//指示此模塊是否是資源
int mdStreamVersion = module.MDStreamVersion;//獲取源數(shù)據(jù)流的版本
Guid versionId = module.ModuleVersionId;//獲取模塊的版本ID
string moduleName = module.Name;//獲取模塊的名稱(chēng),去除路徑的
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("類(lèi)型信息");
i = 0;
foreach (var type in types)
{
TypeAttributes typeAttributes = type.Attributes;//與Type關(guān)聯(lián)的屬性
string typeFullName = type.FullName;//獲取類(lèi)型的完全限定名稱(chēng)
FieldInfo[] typeFields = type.GetFields();//獲取所有的公共字段
EventInfo[] typeEvents = type.GetEvents();//獲取所有的 公共事件
Type[] typeInterfaces = type.GetInterfaces();//獲取所有的公共接口
MemberInfo[] typeMembers = type.GetMembers();//獲取所有的公共成員
MethodInfo[] typeMethods = type.GetMethods();//獲取所有的公共方法
TypeInfo typeInfo = type.GetTypeInfo();//返回指定類(lèi)型的表述形式
string nameSpace = type.Namespace; //指定類(lèi)型的命名空間
string typeName = type.Name;//獲取當(dāng)前成員的名稱(chēng)
ConstructorInfo[] typeConstructors = type.GetConstructors();//類(lèi)型的構(gòu)造函數(shù)
tvNodes[0].Nodes[2].Nodes.Add(string.Format("類(lèi)型:{0}", typeName));
tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("全名稱(chēng):{0}", typeFullName));
tvNodes[0].Nodes[2].Nodes[i].Nodes.Add(string.Format("制定類(lèi)型名稱(chēng):{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>
/// 通過(guò)類(lèi)型獲取節(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");//此處是相對(duì)路徑
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í)再加以研究。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持我們!
上一篇:三十分鐘快速掌握C# 6.0知識(shí)點(diǎn)
欄 目:C#教程
下一篇:C#中字符串的一般性和特殊性
本文標(biāo)題:C# 動(dòng)態(tài)加載程序集信息
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/5851.html
您可能感興趣的文章
- 01-10C#動(dòng)態(tài)創(chuàng)建button的方法
- 01-10WinForm實(shí)現(xiàn)程序一段時(shí)間不運(yùn)行自動(dòng)關(guān)閉的方法
- 01-10C#實(shí)現(xiàn)將程序鎖定到Win7任務(wù)欄的方法
- 01-10C#使用windows服務(wù)開(kāi)啟應(yīng)用程序的方法
- 01-10C#一個(gè)簡(jiǎn)單的定時(shí)小程序?qū)崿F(xiàn)代碼
- 01-10C#動(dòng)態(tài)創(chuàng)建Access數(shù)據(jù)庫(kù)及密碼的方法
- 01-10C#實(shí)現(xiàn)程序等待延遲執(zhí)行的方法
- 01-10C#使用Mutex簡(jiǎn)單實(shí)現(xiàn)程序單實(shí)例運(yùn)行的方法
- 01-10C#獲取動(dòng)態(tài)生成的CheckBox值
- 01-10C#計(jì)算程序執(zhí)行過(guò)程花費(fèi)時(shí)間的方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 04-02jquery與jsp,用jquery


