A requirement of the common language runtime is that .NET-compiled code must belong to an assembly. Assemblies give a scope context to code: The code might be global to the server, or local to an application. And assemblies provide the names for types that are used in common language runtime applications.

In general, the types in an assembly are deployed as an indivisible unit. The assumption is that all types within an assembly were compiled at the same time. To this end, version management is done on an assembly-wide basis. Additionally, types within an assembly can be given more access privileges to one another than types that are outside of the assembly.

Assemblies and Modules

An assembly is a logical collection of type definitions. Within that logical collection, the type definitions may be spread across multiple physical files, or modules. A module is an executable file that contains common language runtime metadata and executable code. All code for a given type exists in exactly one module.

An assembly contains a manifest that is the top-level directory to the adjunct files that contain the actual code. In general, the references to external modules appear as relative paths and are evaluated relative to the locations of the file that contains the assembly manifest. The manifest also contains a list of references to external assemblies that this assembly is dependent upon. When loading an assembly, the common language runtime loader makes sure that all subordinate assemblies can be loaded prior to executing the first line of code.


Each module begins with a module manifest. Note that a module manifest consists primarily of a list of references to external assemblies that the module's types depend on. For example, if a contained type T had a field of type E, and E was defined in an external assembly, the module manifest for T's module would contain a reference to E's assembly.

Exactly one module in an assembly is distinguished by also containing the assembly manifest. The assembly manifest is a superset of a module manifest, because it also contains a list of subordinate files/modules that may contain type definitions. All types defined in subordinate modules are scoped by the name of the containing assembly. Also interesting to note is that the assembly references or manifests contained in its subordinate modules are in addition to those references needed for types defined in the assembly modules themselves.

Private Assemblies

Private assemblies are assumed to be for the exclusive use of a small number of applications and are not generally visible to all applications. Private assemblies must be co-located with the application(s) that use(s) them. A private assembly must be located in the directory that is a descendant of the loading application's root directory. The probe path for private assemblies is always at least ApplicationBase and ApplicationBase\AssemblyName, in which ApplicationBase is the base directory (or URL) of the loading application, and AssemblyName is the name of the assembly.

The probe path can be augmented using an XML configuration file. The common language runtime looks for an XML configuration file with the same name as the loading application, but with a .cfg extension rather than an .exe extension.

Global Assemblies

Global assemblies reside in the Global Assembly Cache (GAC) and are strongly named (or globally unique for an enterprise). They are intended for wide-spread use across applications created by multiple organizations. In general, a global assembly differs from a private assembly only in how it is named. Private assemblies are named using a simple name that matches the file containing the manifest. Global assembly names have three additional components: an originator, a version, and a culture identifier. The originator identifies the organization that developed the component. The version is a four-part version number that identifies the major, minor, build, and revision numbers of the component. The culture identifier indicates what language and region the component is intended for.

When building a global assembly, one must explicitly specify the originator and version, and may optionally specify the culture using compiler attributes. The following code shows the attributes that set the originator to the public key stored in the file jsventures.snk, the version number to, and the culture to U.S. English:

 using System.Runtime.CompilerServices; [assembly: AssemblyKeyFile("jsventures.snk")] [assembly: AssemblyVersion("")] [assembly: AssemblyCultre("en-US")] namespace JSVentures.IceCream {     public class Flavor     {         // Ice Cream flavor stuff goes here     } } 

Global assemblies must be installed into a machine-wide (global) assembly cache known as the GAC. The GAC is located under the %SystemRoot%\Assembly directive. A custom Explorer shell extension allows administrators and users to examine entries in the GAC. Additionally, one can run the gacutil.exe utility to install, uninstall, or list the assemblies in the GAC.

ASP. NET Solutions - 24 Case Studies. Best Practices for Developers
ASP. NET Solutions - 24 Case Studies. Best Practices for Developers
ISBN: 321159659
Year: 2003
Pages: 175 © 2008-2017.
If you may any questions please contact us: