1. Introduction
1.1 About Reflection and Attributes
In "C# 7.0 Essentials", this topic is covered in "Chapter 18 Reflection, Attributes, and Dynamic Programming"; in "C# 7.0 Core Technology Guide", it appears in "Chapter 19 Reflection and Metadata".
Here we can obtain several highly relevant technologies: Reflection, Attributes, Metadata.
Metadata: Programs written in C# are compiled into an assembly, which contains metadata, compiled code, and resources. Metadata includes the following content:
- A description of each type in the program or library;
- Manifest information, including data related to the program itself and the libraries it depends on;
- Custom attributes embedded in the code, providing additional information related to the constructs they annotate.
Reflection: The operation of examining and using metadata and compiled code at runtime is called reflection.
Contents included in an assembly:
2. Assembly Operations
Code compiled from C# generates .dll or .exe files. We can manually load the assembly file using the Assembly class to perform various operations.
The Assembly class is located in the System.Reflection
namespace.
The "C# 7.0 Core Technology Guide" lists common properties and methods of the Assembly class:
Next, we will learn how to use Assembly through code operations.
Create a console project and set assembly description information.
2.1 Getting the Assembly Object
Microsoft's official documentation recommends the following methods for loading assemblies:
- The recommended method for loading an assembly is to use the Load method, which identifies the assembly to be loaded by its display name (for example, "b77a5c561934e089, Version = 2.0.0.0, Culture = neutral, PublicKeyToken ="). The search for the assembly follows the rules described in How the Runtime Locates Assemblies.
- Using ReflectionOnlyLoad and ReflectionOnlyLoadFrom methods, you can load assemblies for reflection but not for execution. For example, you can inspect a 64-bit assembly from code running on a 32-bit platform.
- In rare cases where assemblies must be identified by path, the LoadFile and LoadFrom methods can be provided.
There are generally three ways to get an assembly:
- Assembly.Load()
- Assembly.LoadFrom()
- Assembly.LoadFile()
You can obtain currently referenced assemblies using the following method:
AppDomain.CurrentDomain.GetAssemblies();
Output:
System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
ConsoleApp4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
System.Runtime, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Runtime.Extensions, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Console, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
2.1.1 Runtime Getting Assemblies
Retrieve assemblies through forms such as running types, functions, etc.
Assembly class: public static Assembly? GetAssembly(Type type);
public static Assembly GetCallingAssembly(); public static Assembly? GetEntryAssembly(); public static Assembly GetExecutingAssembly();
Type class:
{type}.AssemblyExplanation of parsing:
Location | Function | Description |
---|---|---|
Assembly | GetAssembly(Type) | Gets the currently loaded assembly that defines the specified type |
Assembly | GetCallingAssembly() | Returns the assembly of the method that calls the currently executing method |
Assembly | GetEntryAssembly() | Gets the executable file of the process in the default application domain. This is the first executable file executed by ExecuteAssembly(String) in other application domains |
Assembly | GetExecutingAssembly() | Gets the assembly that contains the currently executing code |
Type | Assembly | Returns the assembly where a type is located |
2.1.2 Usage Methods
Assembly assem = typeof(Console).Assembly;
Assembly ass = Assembly.GetExecutingAssembly();
2.1.3 Loading Assemblies from Files
Function | Description |
---|---|
LoadFrom(String) | Loads the assembly known by the file name or path |
LoadFrom(String, Byte[], AssemblyHashAlgorithm) | Loads the assembly using the given file name or path, hash value, and hash algorithm |
LoadFrom(String, Evidence) | Loads the assembly given the file name or path and provides security evidence |
LoadFrom(String, Evidence, Byte[], AssemblyHashAlgorithm) | Loads the assembly using the given file name or path, security evidence, hash value, and hash algorithm |
2.1.4 Usage Methods
Assembly ass = Assembly.LoadFrom(@"X:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.0.0\ref\netcoreapp3.0\System.Console.dll");
Additionally, there are many other obscure ways to load assemblies, which are not necessary to list (because I won't).
2.2 Assembly Usage
After obtaining the Assembly object, various operations can be performed.
Common Assembly functions can be viewed in Figure 3.
First, set up two Assembly objects:
Assembly assemA = typeof(Console).Assembly;
Assembly assemB = Assembly.GetExecutingAssembly();
2.2.1 Getting the Fully Qualified Assembly Names
Console.WriteLine("Fully Qualified Assembly Name");
Console.WriteLine(assemA.FullName);
Console.WriteLine(assemB.FullName);
Fully Qualified Assembly Name
System.Console, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
ConsoleApp4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
There is a PublicKeyToken property. As we introduced the method to get assemblies before, using PublicKeyToken, we can also use Load to load assemblies.
However, you can see from the output above that System.Console has a PublicKeyToken value, whereas your created project ConsoleApp4 does not.
2.2.2 AssemblyName
AssemblyName is a type used to fully describe an assembly.
AssemblyName is used to obtain various information about the assembly class and does not have operational functionality; it is only used to acquire metadata information of the assembly.
Instances of AssemblyName can be obtained using the GetName()
method of the Assembly.
Property | Description |
---|---|
CodeBase | Gets or sets the URL location of the assembly. |
ContentType | Gets or sets a value indicating the content type contained in the assembly. |
CultureInfo | Gets or sets the regional settings supported by the assembly. |
CultureName | Gets or sets the regional settings name associated with this assembly. |
EscapedCodeBase | Gets the URI including escape symbols representing the base code. |
Flags | Gets or sets the attributes of the assembly. |
FullName | Gets the full name of the assembly (also known as the display name). |
HashAlgorithm | Gets or sets the hash algorithm used for the assembly manifest. |
KeyPair | Gets or sets the public/private key pair used to create the strong name signature for the assembly. |
Name | Gets or sets the simple name of the assembly. This is usually (but not necessarily) the file name of the assembly's manifest without its extension. |
ProcessorArchitecture | Gets or sets a value that identifies the processor and bitness of the target platform for the executable file. |
Version | Gets or sets the major version, minor version, build number, and revision number of the assembly. |
VersionCompatibility | Gets or sets information related to the compatibility of the assembly with other assemblies. |
AssemblyName assemNameA = assemA.GetName();
AssemblyName assemNameB = assemB.GetName();
Console.WriteLine("Assembly Name: {0}", assemNameA.Name);
Console.WriteLine("Assembly Name: {0}", assemNameB.Name);
// Version
Console.WriteLine("\nVersion: {0}.{1}",
assemNameA.Version.Major, assemNameA.Version.Minor);
Console.WriteLine("Version: {0}.{1}",
assemNameB.Version.Major, assemNameB.Version.Minor);
// Physical file location of the assembly
Console.WriteLine("\nAssembly CodeBase:{0}", assemA.CodeBase);
Console.WriteLine("\nAssembly CodeBase:{0}", assemB.CodeBase);</code></pre>
Output information:
Assembly Name: System.Console
Assembly Name: ConsoleApp4
Version: 4.1
Version: 1.0
Assembly CodeBase: file:///x:/Program Files/dotnet/shared/Microsoft.NETCore.App/3.0.1/System.Console.dll
Assembly CodeBase: file:///X:/Users/whuanle/source/repos/ConsoleApp4/ConsoleApp4/bin/Debug/netcoreapp3.0/ConsoleApp4.dll
In addition to GetName()
, the Assembly class also provides many properties related to assembly information. For example:
- GetName method returns an AssemblyName object that provides access to various parts of the assembly's display name.
- GetCustomAttributes method lists the attributes applied to the assembly.
- GetFiles method provides access to the files in the assembly manifest.
- GetManifestResourceNames method provides the names of resources in the assembly manifest.
2.3 Ways to Load Assemblies
As mentioned above, there are generally three methods to load assemblies:
- Assembly.Load()
- Assembly.LoadFrom()
- Assembly.LoadFile()
The runtime acquisition and LoadFrom
methods have been demonstrated above.
Next, we will continue to introduce Assembly.Load()
and Assembly.LoadFile()
.
2.3.1 Assembly.Load()
Assembly.Load()
loads an assembly in a strongly-typed manner,
where strong name and assembly signature refer to the assembly having a unique and immutable identity.
What constitutes a strong type? It is achieved by adding the following two metadata elements in the manifest:
-
A unique identifier belonging to the author of the assembly;
-
The hash value of the assembly signature, to confirm that the assembly was generated by the author holding its unique identifier;
For more information on this topic, you can refer to section "18.2 Strong Names and Assembly Signatures" in "C# 7.0 Core Technical Guide," and it will not be elaborated here.
Assembly.Load()
loads the assembly while also automatically loading other assemblies that the loaded assembly references, without causing any duplicate loading issues.
Example of usage:
Assembly assemA = Assembly.Load("System.Console");
Assembly assemB = Assembly.Load("ConsoleApp4");
Assembly assemC = Assembly.Load("System.Console, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
Reference: Detailed Explanation of Assembly.Load (c#)
Address: https://www.cnblogs.com/weifeng123/p/8855629.html
Address: https://blog.csdn.net/xuchen_wang/article/details/92773260
2.3.2 Assembly.LoadFile()
Assembly.LoadFile()
is used in the same way as Assembly.LoadFrom
.
Difference: Assembly.LoadFile()
will only load a specified single assembly; Assembly.LoadFrom
will load one assembly and then automatically load other assemblies that this assembly depends on.
文章评论