At the time of COM Specification, the term component was used to represent a COM Class or COM Module (DLL/EXE) in Microsoft Documentation. Whereas in the .NET Framework, this concept is referred to by the name Assembly, which is a software component, and this software component is a plug and play in the software, in the same way, that a hardware component is in any other device. Plug and Play happens.
Assembly in C#
Theoretically, an assembly is in a way equivalent to a COM module. But practically, an Assembly refers to many types (Classes) and Physical Files (.NET PE Files, Bitmap Files, etc.…), which are needed by the CLR to run the application successfully at runtime.
In addition, the Assembly also hosts the IL Code of an application program, and the Assembly itself handles Versioning, Deployment, Security Management, Parallel or Side-by-Side Execution, Sharing, and Reuse.
In simple words, Assembly is a logical DLL or EXE of an application, whereas MANIFEST is a detailed description of the same application, i.e., metadata, along with information about the version of the application, the types to be used, resources, etc.
METADATA is actually machine-readable information of a resource. This information provides various types of details related to the Current Application Program. In .NET, there are Type Definitions, Version Information, External Assembly References, and other Standardized Information Stores of the Types used in the Current Program under METADATA.
When two components, systems, or objects want to have some kind of interaction with each other, then it is necessary that one of the two knows some specific things about the other. In COM Specification, this information was known as Interface Specification, which was implemented by the component provider and used by the developer using the component. But in .NET this requirement is met through METADATA.
.NET MANIFEST – ASSEMBLY METADATA
Assembly MANIFEST is also metadata, which describes various things about the Assembly. Under this metadata, there are details related to the Unique Identity of the Assembly, Total Number of Files Included in the Assembly, Reference to External Assemblies, Exported Types, Exported Resources and Permission Request, etc., which are used by the .NET Platform to provide Cross-Language Interoperability. is done for.
In simple words, whatever information is needed to plug and play the component, that information is available in this manifest, and since all the information exists in the Assembly’s manifest itself, so any information related to the component can be accessed. There is no need to store it in the registry of the Windows operating system, as was the case during the COM specification.
IL or MSIL Code
After compiling the IL Code, i.e., Current Application in an assembly, there is Intermediate Language Code that is generated, which is executed in the CLR Runtime. This IL code usually uses types that are defined in the same Assembly, but it can also refer to any other type stored in another assembly.
When IL Code wants to refer to a Type Exist in the Current Assembly, it does not need to do anything special. But when the Assembly of the current application wants to refer to a type (Class, Structure, Delegate, etc.) stored in another assembly, then it is necessary to define a reference to that external Assembly in the current Assembly.
Also, every Assembly always has an Entry Point, which we refer to by DllMain(), WinMain, or Main(), and we always have to follow this rule. That is, we cannot load and run any assembly on the CLR, which does not have any of these entry points, because whenever the CLR loads and runs an assembly, it searches for any of these entry points. And starts the execution of the code only from the entry point found.
There are basically four types of assemblies in the .NET Framework:
- Static Assemblies
These are .NET PE files, which are created when we compile our .NET program. To create Static Assemblies, we can use any compiler from C #’s csc.exe, C/C++’s cl, or VisualBasic.NET’s vbc.exe.
2. Dynamic Assemblies
These are PE Formatted In-Memory Assemblies, which are dynamically created at the runtime of the application using the classes of System.Reflection.Emit Namespace of .NET Framework.
3. Private Assemblies
These are the Static Assemblies, which are used by a specific application.
4. Public or Shared Assemblies
These are those Static Assemblies, which must have a Unique Shared Name and can be used by any application.
An application can refer to a static path of a private assembly for use or can refer to that private Assembly through an XML-based application configuration file. Assembly in .NET is the smallest unit to which we can associate a version number, whose format is as follows:
Since the assembly MANIFEST of a .NET application contains reference information of an external assembly. Also, that External Assembly also has External Path and Version Information, so now we do not need to get Language Portability by storing/retrieving the Current Application Version’s information in Windows’ Registry File like COM Specification. Because the version and security information of our component is also recorded in the MANIFEST of our Assembly, using which the CLR always loads the shared Assembly of the correct version for the current application.
Creating and Using Assemblies
When we compile as an .EXE or .DLL file by creating a .NET program in Visual Studio or through a text editor, the EXE/DLL file obtained is a Single-Module Assembly File. Creating a Single-Module Assembly is easy because the compiler does the work of creating it at its own level.
But when we want to create Multi-Module Assembly, then we cannot use Visual Studio. In that case, we have to use Command Line Options only. Assembly Linker (al.exe) is one such tool, which can be used to create Multi-Module Assembly.
To use an assembly, first, we have to import that Assembly into our code. To import Assembly, we have to use Syntax of .NET Supported Programming Language. For example, if we are using C# Programming Language, then to import the Assembly named System, we have to use the Using Statement as follows:
Then after creating our program, when we build our Assembly, that is, when we compile our program, then we have to tell our compiler which external Assembly we are referencing. Here also if we are using C# compiler, then we have to specify External Assembly by Command Line Parameters as follows:
C:\compiler\path\>csc /r:system.dll .cs
In this Compile Statement, we are compiling our C# Program File named .cs, whereas, in our Program File, we have imported the Assembly named System, so while compiling the program, we have compiled that system with the “/r:” option. The same External Assembly named .dll is referenced.
Read also: CLR in .NET