C# 動態加載程序集信息。本站提示廣大學習愛好者:(C# 動態加載程序集信息)文章只能為提供參考,不一定能成為您想要的結果。以下是C# 動態加載程序集信息正文
在設計模式的策略模式中,需要動態加載程序集信息,本文通過一個簡單的實例,來講解動態加載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());
}
}
動態加載和反射調用的功能還有很多,不能一一列舉,只能在以後的工作中用到時再加以研究。
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持!
[db:作者簡介][db:原文翻譯及解析]