Assemblies in .NET
An assembly is a basic unit for deployment, versioning, and security. Assemblies come in two forms, either as an executable file (.exe
) or a dynamic-linked library (.dll
). An assembly is a collection of types, resources, and meta-information that forms a logical unit of functionality. Assemblies are loaded into memory only if needed. For .NET Framework applications, assemblies could either be located in the application private folder or shared in the Global Assembly Cache, provided they are strongly-named. For .NET Core applications, this latter solution is not available.
Each assembly contains a manifest that contains the following information:
- The identity of the assembly (such as name and version)
- A file table describing the files that make up the assembly, such as other assemblies or resources (such as images)
- A list of assembly references that contains the external dependencies that the application needs
The identity of an assembly is composed of several parts:
- The name of the file where the name should be compliant with the Windows Portable Executable file format
- A version of the form of
major.minor.build.revision
, such as 1.12.3.0 - The culture that should be locale-agnostic except in the case of satellite assemblies (which are locale-aware assemblies)
- The public key token, which is a 64-bit hash of the private key used to sign the assembly; signed assemblies have strong names that are meant to provide a unique name
You will learn more about assemblies in Chapter 11, Reflection and Dynamic Programming.
Global Assembly Cache (GAC)
As mentioned in the preceding section, .NET Framework assemblies could either be stored locally, in the application folder, or in GAC. This is a machine-wide code cache that enables the sharing of assemblies between applications. Since the release of .NET Framework 4, the default location for the GAC is %windir%\Microsoft.NET\assembly
; however, previously, the location was %windir%\assembly
. GAC also enables storing multiple versions of the same assembly, which is not actually possible in a private folder, since you cannot store multiple files with the same name in the same folder.
To deploy an assembly to the GAC, you could use the Windows SDK utility tool called gacutil.exe
or an installer that is able to work with the GAC. However, an assembly must have a strong name to be deployed to the GAC. A strong-name assembly is an assembly cryptographically signed with a private key that corresponds to a public key distributed with the assembly. You can sign an assembly using the Strong Name tool (sn.exe
).
Note
For more details about how to sign an assembly, please refer to the following document, which describes how to sign an assembly with a strong name: https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-sign-an-assembly-with-a-strong-name.
When you add an assembly to GAC, integrity checks are performed on all of the files contained by the assembly. This is done to ensure that the assembly has not been tampered with. The cryptographic signing ensures that any change to any of the files in the assembly invalidates the signature and only someone that has access to the private key can resign the assembly.
Runtime package store
The GAC is not used for .NET Core assemblies. These are assemblies that can run on any platform and not just Windows. Prior to .NET Core 2.0, the only option for deployment was the application folder. Since version 2.0, however, it is possible to package and deploy applications against a known set of packages that exist in the target environment. This enables faster deployment and lower disk space requirements. Typically, this store is available at /usr/local/share/dotnet/store
on macOS and Linux and C:/Program Files/dotnet/store
on Windows.
The packages available in the runtime package store are listed in a target manifest file that is used while publishing an application. This file has a format that is compatible with the project file format (.csproj
).
Detailing the targeting process is beyond the scope of this chapter, but you can learn more about the runtime package store by visiting the following link: https://docs.microsoft.com/en-us/dotnet/core/deploying/runtime-store.