What Is an Assembly?

What Is an Assembly?

An assembly is basically a deployment unit, a building block of a managed application. Assemblies are reusable, allowing different applications to use the same assembly. Assemblies carry a full self-description in their metadata, including version information that allows the common language runtime to use a specific version of an assembly for a particular application.

This arrangement eliminates what’s known as “DLL Hell,” the situation created when upgrading one application renders another application inoperative because both happen to use the same DLL(s). A typical example of DLL Hell occurred with the release of the game Microsoft Age of Empires II, a sequel to Age of Empires. Because the sequel used a more advanced version of the Microsoft DirectX DLL, which was incompatible with Age of Empires, the original game ceased to work when the sequel was installed. To deal with the situation, Microsoft had to issue a new version of the DirectX DLL that was consumable by both games.

Private and Shared Assemblies

Assemblies are classified as either private or shared. Structurally and functionally, these two kinds of assemblies are the same, but they differ in how they are named and deployed and in the level of version checks performed by the loader.

A private assembly is considered part of a particular application, not intended for use by other applications. A private assembly is deployed in the same directory as the application or in a subdirectory of this directory. This kind of deployment shields the private assembly from other applications, which should not have access to it.

Being part of a particular application, a private assembly is usually created by the same author (person, group, or organization) as other components specific to this application and is thus considered to be primarily the author’s responsibility. Consequently, naming and versioning requirements are relaxed for private assemblies, and the common language runtime does not enforce these requirements. The name of a private assembly must be unique within the application.

A shared assembly is not part of a particular application and is designed to be used widely by various applications. Shared assemblies are usually authored by groups or organizations other than those responsible for the applications that use these assemblies. A prominent example of shared assemblies is the set of assemblies constituting the Microsoft .NET Framework class library.

As a result of such positioning, the naming and versioning requirements for shared assemblies are much stricter than those for private assemblies. Names of shared assemblies must be globally unique. Additional assembly identification is provided by strong names, which use cryptographic public/private key pairs to ensure the name’s uniqueness and to prevent name spoofing. A strong name also provides the consumer of the shared assembly with information about the identity of the assembly publisher. If the common language runtime cryptographic checks pass, the consumer can be sure that the assembly comes from the expected publisher, assuming that the publisher’s private encryption key was not compromised.

Shared assemblies are deployed into the global assembly cache (GAC). The GAC stores multiple versions of shared assemblies side by side. The loader typically looks for the shared assemblies in the GAC.

note

Under some circumstances, an application might need to deploy a shared assembly in its directory to ensure that the appropriate version is loaded. In such a case, the shared assembly is being used as a private assembly, so it is not in fact shared, whether it is strong-named or not.

Application Domains as Logical Units of Execution

Operating systems and run times typically provide some form of isolation between applications running on the system. This isolation is necessary to ensure that code running in one application cannot adversely affect other, unrelated applications. In modern operating systems, this isolation is achieved by using process boundaries, where a process, occupying a unique virtual address space, runs exactly one application and scopes the resources that are available for that process to use.

Managed code execution has similar needs for isolation. Such isolation can be provided at lower cost in a managed application, however, considering that managed applications run under the control of the common language runtime and are verified to be type-safe.

The runtime allows multiple applications to be run in a single operating system process, using a construct called an application domain to isolate the applications from one another. In many respects, application domains are the common language runtime equivalent of an operating system process.

Specifically, isolation in managed applications means the following:

  • Different security levels can be assigned to each application domain, giving the host a chance to run the applications with varying security requirements in one process.

  • Applications can be independently stopped and debugged.

  • Code running in one application cannot directly access code or resources from another application. (Doing so could introduce a security hole.)

  • Faults in one application cannot affect other applications by bringing down the entire process.

  • Each application has control over where the code loaded on its behalf comes from and what version the code being loaded is. In addition, configuration information is scoped by the application.

The following examples describe scenarios in which it is useful to run multiple applications in the same process:

  • ASP.NET runs multiple Web applications in the same process. In ASP/IIS (Internet Information Services), application isolation was achieved by process boundaries, which proved too expensive to scale appropriately.

  • Microsoft Internet Explorer runs code from multiple sites in the same process as the browser code itself. Obviously, code from one site should not be able to affect code from another site.

  • Database engines need to run code from multiple user applications in the same process.

  • Application server products might need to run code from multiple applications in a single process.

Hosting environments such as ASP.NET or Internet Explorer need to run managed code on behalf of the user and take advantage of the application isolation features provided by application domains. In fact, it is the host that determines where the application domain boundaries lie and in what domain user code is run, as these examples show:

  • ASP.NET creates application domains to run user code. Domains are created per application as defined by the Web server.

  • Internet Explorer by default creates one application domain per site (although developers can customize this behavior).

  • In Shell EXE, each application launched from the command line runs in a separate application domain occupying one process.

  • Microsoft Visual Basic for Applications (VBA) uses the default application domain of the process to run the script code contained in a Microsoft Office document.

  • Windows Foundation Classes (WFC) Forms Designer creates a separate application domain for each form being built. When a form is edited and rebuilt, the old application domain is shut down, the code is recompiled, and a new application domain is created.

Because isolation demands that the code or resources of one application must not be directly accessible from code running in another application, no direct calls are allowed between objects in different application domains. Cross-domain communications are limited to passing the objects, which are either copied or accessed via proxy and which fall into one of the following three categories:

  • Unbound objects are marshaled by value across domains. This means that the receiving domain gets a copy of the object to play with instead of the original object.

  • AppDomain-bound objects are marshaled by reference across domains, which means that cross-domain access is always accomplished through proxies.

  • Context-bound objects are also marshaled by reference across domains as well as between contexts within the same domain.

The common language runtime relies on the verifiable type safety of the code to provide fault isolation between domains at a much lower cost than that incurred by the process isolation used in operating systems. Because isolation is based on static type verification, hardware ring transitions or process switches are not necessary.



Inside Microsoft. NET IL Assembler
Inside Microsoft .NET IL Assembler
ISBN: 0735615470
EAN: 2147483647
Year: 2005
Pages: 147
Authors: SERGE LIDIN

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