C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#   Assembly类

C#中Assembly类的使用小结

作者:光泽雨

本文主要介绍了C#中Assembly类详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Assembly 类位于 System.Reflection 命名空间,表示一个可重用、可部署且可版本化的 .NET 程序集。程序集是 .NET 应用程序的基本构建块,包含了类型、资源、元数据和清单。通过 Assembly 类,你可以加载程序集、查询类型信息、动态创建实例、读取自定义特性、访问嵌入资源等。

1. 如何获取Assembly对象

1.1 静态方法(常用)

方法说明
Assembly.GetExecutingAssembly()获取当前正在执行的代码所在的程序集。
Assembly.GetCallingAssembly()获取调用当前方法的方法所在的程序集(性能稍差,慎用)。
Assembly.GetEntryAssembly()获取应用程序的入口程序集(通常是可执行文件)。
Assembly.Load()通过程序集的显示名称或字节数组加载程序集。
Assembly.LoadFrom()从指定文件路径加载程序集(会加载依赖项)。
Assembly.LoadFile()仅加载指定路径的程序集,不自动加载依赖项。
Assembly.ReflectionOnlyLoadFrom()仅用于反射(不可执行代码),.NET Core 5+ 不支持。
 using System.Reflection;
 ​
 // 1. 获取当前程序集
 Assembly asm1 = Assembly.GetExecutingAssembly();
 ​
 // 2. 通过名称加载(需已存在于应用程序域)
 Assembly asm2 = Assembly.Load("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
 ​
 // 3. 从文件加载
 Assembly asm3 = Assembly.LoadFrom(@"C:\MyLibs\MyLibrary.dll");
 ​
 // 4. 获取入口程序集
 Assembly entryAsm = Assembly.GetEntryAssembly();

1.2 通过类型获取

 Assembly asm4 = typeof(MyClass).Assembly;

2. 常用属性

属性说明
FullName程序集完整显示名称(包含名称、版本、区域、公钥令牌)。
Location程序集文件在磁盘上的物理路径(若已加载)。
CodeBase程序集的原始 URI 位置(已过时,建议用 Location)。
ImageRuntimeVersion程序集生成时使用的 CLR 版本(如 v4.0.30319)。
EntryPoint返回程序集入口方法(如 Main 方法),若无则返回 null。
IsDynamic指示程序集是否通过反射发出(Reflection.Emit)动态生成。
Console.WriteLine(asm1.FullName);           // "MyApp, Version=1.0.0.0,        Culture=neutral, PublicKeyToken=null"
Console.WriteLine(asm1.Location);           // "C:\MyApp\bin\Debug\MyApp.exe"
Console.WriteLine(asm1.ImageRuntimeVersion);// "v4.0.30319"

3. 常用方法

3.1 类型反射

方法说明
GetTypes()获取程序集中定义的所有公共类型。
GetExportedTypes()获取程序集中定义的公共类型(可被外部访问)。
GetType(string name)通过类型全名获取 Type 对象。
GetReferencedAssemblies()获取当前程序集引用的所有程序集名称(AssemblyName)。
 Type[] allTypes = asm1.GetTypes();
 foreach (Type t in allTypes)
 {
     Console.WriteLine(t.FullName);
 }
 ​
 Type myType = asm1.GetType("MyNamespace.MyClass");

3.2 动态创建实例

方法说明
CreateInstance(string typeName)创建指定类型(区分大小写)的实例,返回 object。
CreateInstance(string typeName, bool ignoreCase)是否忽略大小写。
CreateInstance(string typeName, bool ignoreCase, BindingFlags binder, object[] args, CultureInfo culture)完整重载,支持参数传递。
// 创建无参实例
 object obj = asm1.CreateInstance("MyNamespace.MyClass");
 ​
 // 创建带参数的实例
 object obj2 = asm1.CreateInstance(
     "MyNamespace.MyClass", 
     false, 
     BindingFlags.Default, 
     null, 
     new object[] { 42, "hello" }, 
     null, 
     null);

3.3 读取自定义特性

方法说明
GetCustomAttributes()获取程序集上定义的所有自定义特性。
GetCustomAttributes(Type attributeType)获取指定类型的特性。
GetCustomAttributesData()获取特性数据(不创建实例,适用于仅反射场景)。
// 获取程序集的 AssemblyTitle 特性
 var titleAttr = asm1.GetCustomAttribute<AssemblyTitleAttribute>();
 Console.WriteLine(titleAttr?.Title);

3.4 访问嵌入资源

方法说明
GetManifestResourceNames()获取程序集中所有嵌入资源的名称。
GetManifestResourceStream(string name)获取嵌入资源的数据流(Stream)。
GetManifestResourceInfo(string name)获取资源的位置等信息。
 // 列出所有嵌入资源
 string[] resources = asm1.GetManifestResourceNames();    //获取程序集中所有嵌入资源的名称
 foreach (string res in resources)
 {
     Console.WriteLine(res);
 }
 ​
 // 读取文本资源
 using (Stream stream = asm1.GetManifestResourceStream("MyApp.Resources.Config.xml"))
 using (StreamReader reader = new StreamReader(stream))
 {
     string content = reader.ReadToEnd();
 }

注意:资源名称通常是命名空间.文件夹名.文件名,需准确指定。

3.5 安全性

方法说明
Evidence获取程序集的证据(用于安全策略,已过时)。
PermissionSet获取程序集所需的权限集。

4. 完整示例:加载外部程序集并调用方法

using System;
 using System.Reflection;
 ​
 public class Program
 {
     public static void Main()
     {
         // 1. 从文件加载程序集
         Assembly pluginAsm = Assembly.LoadFrom(@"C:\Plugins\Calculator.dll");
 ​
         // 2. 获取类型
         Type calcType = pluginAsm.GetType("CalculatorLib.Calculator");
         if (calcType == null)
         {
             Console.WriteLine("类型未找到");
             return;
         }
 ​
         // 3. 创建实例
         object calculator = Activator.CreateInstance(calcType);
         // 或使用 assembly.CreateInstance:
         // object calculator = pluginAsm.CreateInstance("CalculatorLib.Calculator");
 ​
         // 4. 调用方法
         MethodInfo addMethod = calcType.GetMethod("Add", new Type[] { typeof(int), typeof(int) });
         int result = (int)addMethod.Invoke(calculator, new object[] { 3, 5 });
         Console.WriteLine($"3 + 5 = {result}");
 ​
         // 5. 读取程序集特性
         var versionAttr = pluginAsm.GetCustomAttribute<AssemblyFileVersionAttribute>();
         Console.WriteLine($"插件版本: {versionAttr?.Version}");
     }
 }

5. 注意事项

6. 总结

Assembly 类是 .NET 反射机制的核心入口之一。掌握它,你就能动态地探索和操作程序集,实现插件系统、依赖注入、模块化设计、资源提取等功能。关键要理解如何获取程序集对象、查询元数据、创建实例和访问嵌入资源,同时注意性能和安全陷阱。

通过 Assembly 类,你几乎可以获取关于程序集的一切信息,是 .NET 高级编程的必备技能。

代码文件”“运行进程”**的关系:

属性定义现场实操中的含义
Assembly.GetExecutingAssembly().Location当前代码程序集(.dll 或 .exe)所在的磁盘绝对路径。它是静态的“家”。你通过哪个文件启动,它就指哪里。
currentProcess.MainModule.FileName当前操作系统进程对应的可执行文件路径。它是动态的“身份证明”。Windows 记录了这个进程是从哪个 .exe 运行起来的。

到此这篇关于C#中Assembly类的使用小结的文章就介绍到这了,更多相关C# Assembly类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文