Organizing Managed Code: Assemblies


A complete application often consists of many different files. Some files are modulesDLLs or EXEsthat contain code, while others might contain various kinds of resources such as image files. In .NET Framework applications, files that make up a logical unit of functionality are grouped into an assembly. Assemblies, described in this section, are fundamental to developing, deploying, and running .NET Framework applications.

An assembly is one or more files that comprise a logical unit


Metadata for Assemblies: Manifests

Assemblies are a logical construct; there's no single über-file that wraps all of the files in an assembly. In fact, it's not possible to tell what files belong to the same assembly just by looking at a directory listing. Instead, determining which files comprise a particular assembly requires examining that assembly's manifest. As just described, the metadata in a module, such as a DLL, contains information about the types in that module. An assembly's manifest, by contrast, contains information about all of the modules and other files in an assembly. In other words, a manifest is metadata about an assembly. The manifest is contained in one of the assembly's files, and it includes information about the assembly and the files that comprise it. Just as a tool such as Visual Studio generates metadata for each module it compiles, so too it generates an assembly with an appropriate manifest.

Each assembly has a manifest


As Figure 2-6 shows, an assembly can be built from a single file or a group of files. With a single-file assembly, the manifest is stored in the file itself. With a multifile assembly, the manifest is stored in one of the files in the assembly. In either case, the manifest describes the entire assembly, while the metadata in a particular module describes the types in that module. Among the things an assembly's manifest includes are the following:

  • The name of the assembly. All assemblies have a text name and can optionally have a strong name as well, as described in the next section.

  • The assembly's version number. This number has the form <major version>.<minor version>.<build number>.<revision>. For example, the version number for an assembly that's part of a released application might be 1.2.1397.0. Note that versioning is per assembly, not per module.

  • The assembly's culture, indicating the culture or language an assembly supports.

  • A list of all files contained in this assembly, together with a hash value that's been computed from those files.

  • What other assemblies this one depends on and the version number of each of those dependent assemblies.

Figure 2-6. An assembly is often just a single DLL, but it can also include more than one file.


An assembly's manifest contains the assembly's name, its version number, and more


Most assemblies consist of just a single DLL. Whether it contains one file or multiple files, however, an assembly is logically an indivisible unit. For example, assemblies define a boundary for scoping types. To the CLR, a type name really consists of the name of the type together with the name of the assembly in which the type is defined.

Assemblies define a scope for types


One important corollary of the way assemblies are structured is that, unlike COM classes, CLR classes don't have associated registry entries (unless they are also accessible as COM classes for backward compatibility, an option described in Chapter 4). When the CLR needs to find a class in some other assembly, it does not look up the class in the registry. Instead, it searches according to a well-defined (although slightly complex) algorithm that's described later in this chapter.

Assemblies don't require registry entries


Requiring no registry entries also means that installing an assembly can entail simply copying its constituent files to an appropriate directory on the target machine's disk. Similarly, an assembly can often be uninstalled by simply deleting its files. Unlike older COM-based applications, software built on the .NET Framework doesn't need to modify the system registry.

Installing a .NET Framework application might require just copying its assemblies


Categorizing Assemblies

There are various ways to categorize assemblies. One distinction is between static and dynamic assemblies. Static assemblies are produced by a tool such as Visual Studio, and their contents are stored on disk. Most developers will create static assemblies, since the goal is usually to build an application that can be installed on one or more machines and then executed. It's also possible to create dynamic assemblies, however. The code (and metadata) for a dynamic assembly is created directly in memory and can be executed immediately upon creation. Once it has been created, a dynamic assembly can be saved to disk, then loaded and executed again. Probably the most common examples of dynamic assemblies are those created by ASP.NET when it processes .aspx pages, a topic covered in Chapter 5.

Both static and dynamic assemblies exist


Another way to categorize assemblies is by how they are named. Completely naming any assembly requires specifying three things: the assembly's name; its version number; and, if one is provided, the culture it supports. All assemblies have simple text names, such as "AccountAccess," but an assembly can also have a strong name. A strong name includes the usual three parts of an assembly name, but it also includes a digital signature computed on the assembly and the public key that corresponds to the private key used to create that signature. Strong names are unique and so can be used to identify a particular assembly unambiguously. If desired, it's also possible to embed the certificate of the entity creating an assembly's digital signature in the assembly itself. This allows anyone using the assembly to decide whether they trust this entity and so are willing to execute the assembly.

An assembly can have a strong name


Strong-named assemblies have their version numbers automatically checked by the CLR when they're loaded. Version control for assemblies without strong names, however, is the responsibility of the developer creating and using those assemblies. Because assemblies have version numbers, it's possible for multiple versions of the same assembly to be installed on the same machine at the same time. And because an assembly can specify exactly which version it requires of every other assembly it depends on, the pain that has resulted from DLL conflicts in the past can be minimized.

The CLR performs version checking on assemblies with strong names


Before .NET, installing a new version of a DLL required by one application would commonly break another application that relied on that same DLL. Poetically referred to as DLL hell, one of the goals of the .NET Framework was to address this problem. Using strong-named assemblies, a CLR-based application can insist on a particular version of each assembly it depends on without restricting other applications' use of new versions. Developers must still pay attention, however, or conflicts might arise. For example, suppose two versions of an assembly each write to the same temp file. Unless they agree on how this file should be shared, running both versions at once will lead to problems.

Assemblies can minimize DLL hell





Understanding. NET
Understanding .NET (2nd Edition)
ISBN: 0321194047
EAN: 2147483647
Year: 2004
Pages: 67

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net