ホームページ >バックエンド開発 >C#.Net チュートリアル >C#の動的に読み込まれるアセンブリ情報の詳細説明(図)
デザインパターンのストラテジーモードでは、アセンブリ情報を動的にロードする必要があります。この記事では、簡単な例を使用して、Dllを動的にロードするために必要な知識ポイントを説明します。以下のエディターで見てみましょう
デザインモードのストラテジモードでは、アセンブリ情報を動的にロードする必要があります。この記事では、Dll を動的にロードするために必要な知識ポイントを簡単な例を使用して説明します。関連する知識ポイント:
名前空間
の下のAssembly クラスは、再利用可能でバージョン競合がなく、自己記述型の共通言語ランタイム アプリケーションのビルディング ブロックであるアセンブリを表します。
Moduleクラスはモジュールへのリフレクションの実行を表現し、アセンブリのモジュール情報を表現します。 System 名前空間の下の
interface型、array型、値型、列挙型、型パラメーター、ジェネリック型定義、および開いた構造または閉じた構造のジェネリック型。
properties を検出し、フィールド メタデータへのアクセスを提供します。
constructor のプロパティを検出し、コンストラクターのメタデータへのアクセスを提供します。
からオブジェクト type を作成したり、既存のリモート オブジェクトへの 参照 を取得したりするための特定のメソッドが含まれています。このクラスは継承できません。
Search メソッドのメンバーとタイプを制御するフラグを指定します。メソッドを取得するとき、次の図に示すように 2 番目のパラメーターが使用されます
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()); } }動的ロードとリフレクション呼び出しの関数が多数あります、1つずつ列挙することはできません。列挙は、将来の作業で使用するときにのみ検討できます。
以上がC#の動的に読み込まれるアセンブリ情報の詳細説明(図)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。