An assembly contains one or more .NET data types compiled into the Microsoft Intermediate Language (MSIL); in other words, an assembly contains the code that the common language runtime executes. The .NET Framework uses the assembly as the basic unit of deployment and versioning and, most importantly for our purposes, as the basic security boundary. In the following chapters, we will demonstrate how the .NET Framework uses assemblies to enforce security policy; in this section, however, we provide a brief overview of assemblies as a foundation for more advanced topics.
Microsoft Intermediate Language
When you compile a .NET source file, the compiler converts contained data types to the MSIL, which consists of a series of CPU-independent instructions. The .NET Framework compiles the MSIL describing your data type into instructions for a specific CPU at execution; this approach allows .NET applications to be deployed to different CPU architectures without having to recompile the source code. Consult the .NET documentation for further information about MSIL.
Each assembly consists of the following:
The assembly manifest contains metadata elements that describe the assembly, summarized as follows:
A text string specifying the assembly's name
A string in the form a.b.c.d, where a and b are major and minor version numbers, and c and d are revision and build numbers
Information on the culture or language that the assembly supports, for example, "en-US" for U.S. English or "fr-CA" for Canadian French
Details of the public key used to create the assembly strong name; see Section 2.4 for further information
Lists all of the files that comprise the assembly; as we explain later, assemblies can be made up of more than one file
Provides information about the data types that are exported from this assembly for use in other assemblies
Lists the details of any other assemblies that this assembly depends on
A set of human-readable strings that provide additional information about an assembly, including trademark and copyright restrictions, product and company names, and a description of the assembly contents
This part of the assembly contains information about the data types contained in the MSIL code portion of the assembly, described later.
The MSIL code section of the assembly contains the MSIL statements that will be executed by the .NET Framework runtime, describing one or more .NET types.
There are a set of resources, such as icons and sounds, that the application uses.
There are two types of assembly; each type differs in where the assembly contents are stored. The simplest and most common type is a single-file assembly, where all of the assembly contents are stored in a single file. As shown by Figure 2-1, the four assembly components are contained in the file named SingleFileAssembly.dll.
The second assembly type is a multifile assembly, where the contents of the assembly are stored in more than one file, as illustrated by Figure 2-2.
In a multifile assembly, the assembly metadata and any resources are stored in one file (MultiFileAssembly.dll in Figure 2-1), while the MSIL code is contained in one or more modules, each of which contains one or more data types and any associated type metadata. The assembly is made up of all three files, which must be deployed together; there is no association between the files enforced by the filesystemthe relationship between the files is described by the file list element of the assembly metadata.
The advantage of a multifile assembly is that each module can contain types written in a different .NET language; in Figure 2-2, we illustrate this by including the CSharpCode.netmodule and VBCode.netmodule files in the assembly, representing data types written in C# and Visual Basic .NET, respectively. In the next section, we demonstrate how to create an assembly using modules written in different languages.
Each assembly can have one of three "flavors," depending on the intended function of the assembly, summarized as follows:
A library assembly contains .NET types that are consumed by other assemblies. A library assembly cannot be executed.
An executable assembly can be executed as an application, but the types defined in the assembly cannot be used by other assemblies.
A Windows executable assembly is a variation of an executable assembly that is specifically for GUI applications.
This brief overview of assemblies should provide you with enough information to understand the rest of this chapter and the content presented in the rest of this book. Chapter 4 provides more information about the role of assemblies in the life cycle of a .NET application.