Component Deployment


An assembly is used by the .NET architecture to support the sharing and reuse of code. All classes must exist within an assembly in order to be creatable by the CLR. The assembly contains the metadata that the CLR uses to allow the object to function. Without an assembly, the component cannot function. In the past, you could store code in a DLL and use DLLs as loadable modules within an application. The difference is in the metadata. A DLL was just a block of code “ there was no knowledge of what it did outside of the developer that was familiar with it. The metadata associated with an assembly provides that kind of information.

What Are Assemblies?

There is no concept of an assembly as a file “ there is no such thing as a .assembly file to worry about now. The assembly is a collection of files that together make up the assembly. The only requirement is that these files need to all reside in the same directory on the disk. When they are placed into an assembly, the CLR treats all these as a single unit.

click to expand
Figure 17-6:

As shown in Figure 17-6, the manifest is what is used to describe the contents of the application. The manifest can either be embedded within a single DLL, as seen in the single file assembly, or can be in a separate file, as is the case with the multi-file assembly. When looking at DLLs in .NET, they are just a bit different from what they were in COM or Win32. While the extension is the same, they are executed by the CLR, instead of being executed as native code.

The assembly can be thought of as a logical DLL. In the past, the developer could distribute components or resources through the deployment of a DLL. Now, the developer can distribute the pieces of an assembly in the same way. The main difference is that the DLL needed some other information somewhere “ usually in the registry “ to tell the system that it was there ready to run. With an assembly, it carries that information along with it, in its metadata.

An assembly is not an application. An application is built from one or more assemblies. The assemblies that make up an application can be deployed in a number of different ways. Since an assembly contains its own metadata, it is capable of telling the operating system all about itself. It does not rely on entries into the registry to describe itself.

This association of metadata with executable code simplifies the distribution of an application. All the developer needs to do to deploy an application is simply to copy all of the assemblies that make up the application to a directory on the disk. This is known as XCOPY deployment , since the only tool required to deploy the files to disk is the XCOPY console command. When the application is first executed, the metadata within the assemblies tells the system all that it needs to know in order to execute the application. As seen earlier, this may not always be the case. If the application uses serviced components, these need to be registered with COM+.

.NET applications can also use more traditional installation mechanisms to distribute applications built out of assemblies. This includes building an .msi file and using the Windows Installer to deploy the files into the correct location. Likewise, you can build a .CAB file and have a browser download the file to the system and execute the application. In either case, all that the installation mechanism is responsible for is getting the proper files into the proper location on the destination system “ no information about the assemblies needs to be added to the registry of the target system.

Assemblies and Versioning

There are currently two problems with the Win32 architecture that have combined to create what is known as DLL Hell . In DLL Hell, there is no control entity that is responsible for all of the DLL files installed onto a system. Information about a COM DLL is held in the registry. It can be easily overwritten by another application. For DLLs that aren't COM DLLs, there is no entry whatsoever in the registry. An application install program can also overwrite an existing DLL. This can play havoc with any existing application that was relying on that particular DLL performing a specific function when a method is called.

One of the specific problems with Win32 is that there is no system-level enforcement of versioning rules between components. It is left up to 'best practices' coding, which says that once an interface is published it can never be changed, but there is nothing in the operating system that explicitly prevents this from happening.

The other problem is that there is no common way for an application to say that it needs version 1.2.1.1234 of a particular component. It is left up to the developer to check the version of a DLL before calling into it. If that check is not done, and the application finds a different version, the code that it is relying on may no longer be there, or it may not perform the function that it expects, even if the interface is still intact. To combat this, Windows 2000 added System File Protection. This is an OS feature that can stop any installation program from overwriting any system DLLs.

The CLR extends this support by allowing developers to specify the specific version of a component for their application to use. It provides all of the support to make sure that the proper version is located and used for the requesting application. In doing this, it also allows for the execution of code from two similar components, only differing in version. This is known as side-by-side execution and is discussed a bit later in the chapter.

Assembly Manifest

In order for an assembly to describe itself to the CLR, it must contain a set of metadata. This metadata is contained in the assembly's manifest. The manifest contains the metadata required to specify:

  • The assembly version

  • The security information for the assembly

  • The scope of the assembly

  • Information to resolve references to the resources and classes of the assembly

The manifest for an assembly can either be stored in an EXE or DLL file, or in a standalone file. Remember that the assembly can be made up of one or more files “ in which case there isn't a specific file that contains the entire assembly. In a single file assembly, the manifest is part of the DLL or EXE file that is the assembly.

The manifest of an assembly lists all of the files and resources that make up the assembly. It also lists all the classes and types defined in the assembly, and specifies which resources or files within the assembly map to which classes or types. The manifest also identifies any other assemblies on which it is dependent.

In creating a multi-file assembly, the Assembly Generation tool ( AL.EXE ) is used to create the manifest for the assembly. To create a multi-file assembly, compile the individual source files without an assembly. Then the AL tool is used to read through the compiled modules and create an assembly for the full set of modules.

Metadata

The manifest will specifically contain these pieces of metadata:

  • Assembly name

  • Version information

  • Assembly file list

  • Type reference information

  • Referenced assemblies

Let's look at each of them in detail.

Assembly Name

This is a textual string name that identifies the assembly. When an assembly is used by one application, the developer can generally enforce a unique name for each assembly, thus preventing name collisions. However, when an assembly is designed to be shared, a more unique naming method must be used. This is called a strong name , and creating one allows the assembly to be stored in the global assembly cache . The global assembly cache is used to store assemblies that can be used by several applications on a machine.

To store an assembly into the global assembly cache, there are three steps to be followed:

  1. Create a strong name for the assembly using the SN.EXE tool. This tool will generate a file that contains the necessary public and private keys to define a strong name.

  2. Pass the contents of that file to the Assembly Generation Tool ( AL.EXE ) to create an assembly with a strong name associated with it.

  3. Use the Global Assembly Cache Tool ( GACUTIL.EXE ) to install the assembly into the global assembly cache. This is a tool that is used to manipulate the contents of the global assembly cache, including adding components to the GAC.

Version Information

The components of the version number are the major and minor version numbers, a build number, and a revision number. This is represented as a set of four numbers with the format:

 <major version>.<minor version>.<build number>.<revision> 

When the CLR is checking to see if an assembly is the proper version, it first checks the major and minor version numbers. These must match in order for the assembly to be compatible. If these two numbers match but the build number is different, then as long as the build number of the assembly is greater than the build required by the application, it can be assumed to be backwards -compatible with the version expected by the application.

Assembly File List

This lists each file contained in the assembly, along with the relative path to the file. For version 1 of the .NET Framework, all files in an assembly must be in the same directory as the manifest file. This only holds true for a multi-file assembly.

Type Reference Information

Maps all of the types included in the assembly to the specific file in the assembly that contains the type. This is necessary so that any types referenced within the classes contained in the assembly can be resolved by the runtime.

Referenced Assemblies

This lists all of the other assemblies that are statically referenced within the types contained in this assembly. Each entry contains the name of the assembly along with the required version information.

Custom Metadata

There is also custom metadata that can be included by the developer. Only the developer can use this information “the CLR does not use this information in any way. There are two sets of custom assembly metadata. The first set is made up of nine classes from the System.Reflection namespace. Use this namespace to query the values for this metadata at runtime. System.Reflection metadata includes:

  • Company information

  • Build information, such as 'Retail' or 'Debug'

  • Copyright information

  • Additional naming and version information

  • Assembly title and description

  • Product and Trademark information

The second set is made up of classes from the System.Runtime.CompilerServices namespace. This metadata includes:

  • Cultures or spoken languages supported by the assembly, but not programming languages.

  • Operating systems and processors the assembly has been built to support. Version 1 of the CLR does not use this information.

Self-Describing Components

With other application architectures, the only way for components to communicate is through a binary interface. If these components were written in different languages, there is a good chance that the way the data was stored is different as well. This leads to problems in the communication between these two components. In the .NET architecture, the metadata that is presented by each assembly helps to alleviate this confusion. The confusion is further alleviated through the common types of the CLR.

Since the components within an assembly are so thoroughly defined by the metadata, the developer can even define a new class that inherits from an existing class directly from the compiled code “you don't need to access the sourcecode to do this. In fact, the components do not even need to be in the same language, as long as both are managed components. This was seen in an example earlier in the chapter.

The assemblies and the components within them are said to be self-describing . This means that they carry all the information that other components need to know in order to interact with them. This information is all carried within the metadata of the assembly. There are no more IDL files in the .NET Architecture or public header files that get out of sync with the executables, and you can always be sure that the metadata information being used by the runtime is the proper metadata for the code being executed, since they are held together in the assembly.

Side-by-Side Execution

The ability to run multiple versions of the same component at the same time is a very valuable feature of the CLR. It can even execute two versions of the same component within the same process. The ability to do this is called side-by-side execution . By allowing this, the .NET architecture offers the developer an advantage over architectures such as COM. While there have been ways in the past to do side-by-side execution, its implementation in .NET frees the developer from most of the worries associated with doing it. By handling it in the plumbing of the CLR, the developer only has to worry about the business-specific code in their application.

When creating new versions of a component, a developer doesn't have to worry as much about maintaining compatibility with previous versions. Since the older component can run right alongside the new component, and the application using the component knows which version of the component to use, both can co-exist peacefully on the same machine. There are some precautions that the developer must take into account when having components that will run side-by-side with previous versions.

For example, if the component is relying on a physical file as a data cache, two components executing side-by-side will try to access the same file. The components would need to be written such that they keep the file in a location that is dependent on the version of the component being executed.




Professional ASP. NET 1.1
Professional ASP.NET MVC 1.0 (Wrox Programmer to Programmer)
ISBN: 0470384611
EAN: 2147483647
Year: 2006
Pages: 243

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