A .NET Assembly is a fundamental building block of .NET applications. It is a compiled code library that contains all the necessary components (such as code, metadata, and resources) to run an application or a part of an application. In .NET, everything is packaged into assemblies, which can be executable files (EXEs) or libraries (DLLs).
Key Features of .NET Assemblies
-
Code (MSIL)
- An assembly contains Microsoft Intermediate Language (MSIL) code, which is platform-independent. The MSIL code is compiled into machine code by the Common Language Runtime (CLR) when the program is run, using the Just-In-Time (JIT) compiler.
-
Metadata
- Assemblies contain metadata, which is information about the types, methods, properties, and other elements defined in the code. The metadata enables the CLR to understand the types of data and objects being used in the program. It also supports reflection, allowing programs to inspect their structure at runtime.
-
Resources
- Assemblies can include resources like images, strings, icons, or configuration data. These resources are used by the application and are often embedded within the assembly.
-
Manifest
- The assembly includes a manifest, which contains information about the assembly itself. This includes its version, culture, and any referenced assemblies (other libraries or components the assembly relies on).
Types of Assemblies
Assemblies in .NET can be categorized into two main types:
-
Private Assemblies
Private assemblies are intended for use by a single application and are stored in the application’s directory. They are typically not shared between different applications.
-
Shared Assemblies
Shared assemblies are intended to be used by multiple applications. They are stored in a central location, like the Global Assembly Cache (GAC), so they can be accessed by any application that needs them.
Components of a .NET Assembly
A .NET assembly consists of the following components:
-
Assembly Manifest:
- The manifest is a crucial part of an assembly and contains essential metadata about the assembly. It describes the assembly's version, culture, security information, references to other assemblies, and more.
-
Type Metadata:
- This includes information about the types defined in the assembly, such as classes, methods, fields, and properties. It tells the CLR how to load and manage types in memory.
-
IL Code:
- The assembly contains Microsoft Intermediate Language (MSIL) code, which is the language the CLR uses before compiling it into native machine code. The MSIL code is cross-platform and not dependent on the operating system or hardware.
-
Resources:
- Resources like images, localized strings, or other data are often embedded in the assembly. These resources can be used by the application at runtime.
Characteristics of Assemblies
-
Self-Describing:
- An assembly is self-describing, meaning it includes enough information (metadata) to define the assembly, its types, and the relationships to other assemblies. The metadata in the assembly allows the CLR to understand what the assembly does and how to load it correctly.
-
Versioning:
- Assemblies in .NET support versioning, which means that an assembly can specify a version number. This allows for the correct version of the assembly to be loaded at runtime, ensuring compatibility with applications.
-
Strong Names:
- Assemblies can be given a strong name, which is a unique identifier for the assembly, including the name, version, culture, and a public key token. Strong names help avoid naming conflicts between assemblies and ensure that the correct version of the assembly is loaded.
Assembly Loading
When an application runs, the CLR uses the assembly to load the types and execute the code. This is done in several steps:
-
Loading the Assembly:
- The CLR loads the assembly into memory when required by the application. It locates the assembly based on its reference in the application's manifest, the assembly’s strong name, or other location specifications.
-
JIT Compilation:
- The CLR uses the Just-In-Time (JIT) compiler to convert the MSIL code within the assembly into native machine code for execution on the current hardware.
-
Type Resolution:
- The CLR resolves the types within the assembly to ensure they are compatible and can be used correctly in the application. It also manages references to other assemblies and loads them if needed.
Global Assembly Cache (GAC)
The Global Assembly Cache (GAC) is a central repository used to store shared assemblies. Assemblies placed in the GAC are available for use by any application on the system. Assemblies in the GAC must have a strong name to ensure they can be uniquely identified and correctly versioned.
- Why use the GAC?
- Shared Assemblies: When an assembly is meant to be used by multiple applications (like a utility library), the GAC provides a central place to store it.
- Version Control: The GAC supports versioning, meaning that different applications can use different versions of the same assembly if needed.
Building and Managing Assemblies
Summary of .NET Assemblies
- Assemblies are the core units of deployment and execution in .NET.
- They contain compiled code, metadata, resources, and manifests.
- There are two main types of assemblies: private assemblies (for single applications) and shared assemblies (stored in the GAC for multiple applications).
- Managed code in .NET is executed from assemblies, with the CLR handling many runtime tasks such as memory management and security.
- Assemblies support versioning and can be strongly named for security and consistency.
- The GAC is used for storing shared assemblies that need to be used by multiple applications.
In short, assemblies are a key concept in .NET, providing a well-organized way to package and manage code, resources, and metadata for .NET applications.