Ludzie pragną czasami się rozstawać, żeby móc tęsknić, czekać i cieszyć się z powrotem.
5.1 Modules in the Manifest
Assemblies can consist of more than one module. In such a case, the manifest includes a hash code identifying each module to ensure that when the program executes, only the proper version of each module is loaded. If you have multiple versions of a given module on your machine, the hash code ensures that your program will load properly.
The hash is a numeric representation of the code for the module, and if the code is changed, the hash will not match.
17.5.2 Module Manifests
Each module has a manifest of its own that is separate from the assembly manifest. The module manifest lists the assemblies referenced by that particular module. In addition, if the module declares any types, these are listed in the manifest along with the code to implement the module. A module can also contain resources, such as the images needed by that module.
17.5.3 Other Required Assemblies
The assembly manifest also contains references to other required assemblies. Each such reference includes the name of the other assembly, the version number and required culture, and, optionally, the other assembly's originator. The originator is a digital signature for the developer or company that provided the other assembly.
page 351
Programming C#
Culture is an object representing the language and national display
characteristics for the person using your program. It is culture that determines, for example, whether dates are in month/date/year format or date/month/year
format.
17.6 Multi-Module Assemblies
A single-module assembly has a single file that can be an EXE or DLL file. This single module contains all the types and implementations for the application. The assembly manifest is embedded within this module.
A multi-module assembly consists of multiple files (zero or one EXE and zero or more DLL files, though you must have at least one EXE or DLL). The assembly manifest in this case can reside in a standalone file, or it can be embedded in one of the modules. When the assembly is referenced, the runtime loads the file containing the manifest and then loads the required modules as needed.
17.6.1 Benefiting from Multi-Module Assemblies
Multi-module assemblies have advantages for real-world programs, especially if they are developed by multiple developers or are very large.
Imagine that 25 developers are working on a single project. If they were to create a single-module assembly to build and test the application, all 25 programmers would have to check in their latest code simultaneously, and the entire mammoth application would be built. That creates a logistical nightmare.
If they each build their own modules, however, the program can be built with the latest available module from each programmer. This relieves the logistics problems; each module can be checked in when it is ready.
Perhaps more importantly, multiple modules make it easier to deploy and to maintain large programs. Imagine that each of the 25 developers builds a separate module, each in its own DLL.
The person responsible for building the application would then create a 26th module with the manifest for the entire assembly. These 26 files can be deployed to the end user. The end user then need only load the one module with the manifest, and he can ignore the other 25. The manifest will identify which of the 25 modules has each method, and the appropriate modules will be loaded as methods are invoked. This will be transparent to the user.
As modules are updated, the programmers only need to send the updated modules (and a module with an updated manifest). Additional modules can be added and existing modules can be deleted; the end user continues to load only the one module with the manifest.
In addition, it is entirely likely that not all 25 modules will need to be loaded into the program. By breaking the program into 25 modules, the loader can load only those parts of the program that are needed. This makes it easy to shunt aside code that is only rarely needed into its own module, which might not be loaded at all in the normal course of events. Although this was the theory behind DLLs all along, .NET accomplishes this without "DLL Hell," a monumental achievement described later in this chapter.
page 352
Programming C#
17.6.2 Building a Multi-Module Assembly
To demonstrate the use of multi-module assemblies, the following example creates a couple of very simple modules that you can then combine into a single assembly. The first module is a Fraction class. This simple class will allow you to create and manipulate common fractions. Example 17-1
illustrates.
Example 17-1. The Fraction class
namespace ProgCS
{
using System;
public class Fraction
{
public Fraction(int numerator, int denominator)
{
this.numerator = numerator;
this.denominator = denominator;
}
public Fraction Add(Fraction rhs)
{
if (rhs.denominator != this.denominator)
{
throw new ArgumentException(
"Denominators must match");
}
return new Fraction(
this.numerator + rhs.numerator,
this.denominator);
}
public override string ToString( )
{
return numerator + "/" + denominator;
}
private int numerator;
private int denominator;
}
}
Notice that the Fraction class is in the ProgCS namespace. The full name for the class will be ProgCS.Fraction.
The Fraction class takes two values in its constructor: a numerator and a denominator. There is also an Add( ) method, which takes a second Fraction and returns the sum, assuming the two share a common denominator. This class is simplistic, but it will demonstrate the functionality necessary for this example.