Assemblies are the deployment units of .NET applications .. NET application consist of one or more assemblies .. NET executables with the usual extension EXE or DLL are known by the term assembly. What’s the difference between an assembly and a native DLL or EXE? Though they both have the same file extension, .NET assemblies include metadata that describe all the types that are defined’in the assembly with information about its members – methods, properties, events, and fields.
The metadata of .NET assemblies also give information about the files that belong to the assembly, version information, and the exact information about assemblies that are used .. NET assemblies are the answer to the DLL hell we’ve seen previously with native DLLs.
Assemblies are self-describing installation units, consisting of one or more files. One assembly could be a single DLL or EXE that includes metadata, or it can be made of different files, for example, resource files, modules, and an EXE.
Assemblies can be private or shared. With simple. ET applications, using just private assemblies is the best way to work. No special management, registration, versioning, and so on is needed with private assemblies. The only application that could have version problems with private assemblies is your own application. Other applications are not influenced because they have their own copies of the assemblies. The private components you use within your application are installed at the same time as the application itself. Private assemblies are located in the same directory as the application or subdirectories thereof. This way you shouldn’t have any versioning problems with the application. No other application will ever overwrite your private assemblies. Of course, it is still a good idea to use version numbers for private assemblies too. This helps a lot with code changes, but it’s not a requirement of .NET.
With shared assemblies, several applications can use the same assembly and have a dependency on it. Shared assemblies reduce the need for disk and memory space. With shared assemblies, many rules must be fulfilled – a shared assembly must have a version number, a unique name, and usually it’s installed in the global assembly cache (GAC).
Features of Assemblies
The features of assemblies can be summarized as follows:
- Assemblies are self-describing. It’s no longer necessary to pay attention to registry keys for apartments, to get the type library from some other place, and so on. Assemblies include metadata that describes the assembly. The metadata includes the types exported from the assembly and a manifest; the next section describes the function of a manifest.
- Version dependencies are recorded inside an assembly manifest. Storing the version of any referenced assemblies in the manifest makes it possible to easily find deployment faults because of wrong versions available. The version of the’ referenced assembly that will be used can be configured by the developer and the system administrator. Later in this chapter, you learn which version policies are available and how they work.
- Assemblies can be loaded side by side. With Windows 2000 you already have a side-by-side feature ,where different versions of the same DLL can be used on a system .. NET extends this functionality of Windows 2000,allowing different versions of the same assembly to be used inside a single process! How is this useful? If assembly A references version 1 of the shared assembly Shared, and assembly B uses version 2 of the shared assembly Shared, and you are using both assembly A and B, you need both versions of the shared assembly Shared in your . application – and with .NET.both versions are loaded and used.
- Application isolation is ensured using application domains. With application domains a number of applications can run independently inside a single process. Faults in one application cannot directly affect other applications inside the same process.
- Installation’can be as easy as copying the files that belong to an assembly. An xcopy can be enough. This feature is named ClickOnce deployment. However, there are cases in which ClickOnce deployment cannot be applied, and a normal Windows installation is required. Deployment of applications is discussed.
An assembly consists of assembly metadata describing the complete assembly, type metadata describing the exported types and methods, MSIL code, and resources. All these parts can be inside of one file or spread across several files.
the assembly metadata, type metadata, MSILcode, and resources are all in one file – Component. dll. The assembly consists of a single file.
The second example shows a single assembly spread across three files .Component. dll has assembly meta data, type metadata, and MSILcode, but no resources. The assembly uses a picture from picture. jpeg that is not embedded inside Component.dll, but is referenced from within the assembly metadata. The assembly metadata also references a module called ut il. netmodule, whichitself includes only type metadata and MSILcode for a class. A module has no assembly metadata, thus the module itself has no version information; it also cannot be installed separately. All three files in is example make up a single assembly; the assembly is the installation unit. It would also be possible to put the manifest in a different file.
An important part of an assembly is a manifest, which is part of the meta data. It describes the assembly with all the information that’s needed to reference it and lists all its dependencies. The parts of the manifest are as follows:
- Identity – Name, version, culture, and public key.
- A list of files – Files belonging to this assembly. A single assembly must have at least one file but may contain a number of files.
- A list of referenced assemblies – All assemblies used from the assembly are documented inside the manifest. This reference information includes the version number and the public key, which is used to uniquely identify assemblies. The public key is discussed later in this chapter.
- A set of permission requests – These are the permissions needed to run this assembly. You can find more information about permissions .
- Exported types – These are included if they are defined within a module and the module is referenced from the assembly; otherwise, they are not part of the manifest. A module is a unit of reuse. The type description is stored as metadata inside the assembly. You can get the structures and classes with the properties and methods from the metadata. This replaces the type library that was used with COM to describe the types. For the use of COM clients it’s easy to generate a type library out of the manifest. The reflection mechanism uses the information about the exported types for late binding to classes.
Namespaces, Assemblies, and Components
You might be a little bit confused by the meanings of namespaces, types, assemblies, and components. How does a namespace fit into the assembly concept? The namespace is completely independent of an assembly. You can have different namespaces in a single assembly, but the same namespace can be spread across assemblies. The namespace is just an extension of the type name – it belongs to the name of the type.
For example, the assemblies msconfig and system contain the namespaceSystem. Threading among many other namespaces. Although the assemblies contain the same’namespaces, you will not find the same class names.
Private and Shared Assemblies
Assemblies can be shared or private. A private assembly is found either in the same directory as the application, or within one of its subdirectories. With a private assembly, it’s not necessary to think about naming conflicts with other classes or versioning problems. The assemblies that are referenced during the build process are copied to the application directory. Private assemblies are the usual way to build assemblies, especially when applications and components are built within the same company.
Although it is still possible to have naming conflicts with private assemblies (multiple private assemblies may be part of the application and they could have conflicts, or a name in a private assembly might conflict with a name in a shared assembly used by the application), naming conflicts are greatly reduced. If you find you’ll be using multiple private assemblies or working with shared assemblies in other applications, it’s a good idea to utilize well-named namespaces and types to minimize naming conflicts.
When using shared assemblies, you have to be aware of some rules. The assembly must be unique and therefore must also have a unique name called a strong name. Part of the strong name is a mandatory version number. Shared assemblies will mostly be used when a vendor, different from that of the application, builds the component, or when a large application is split into sub projects. Also, some technologies such as .NET Enterprise Services require shared assemblies in specific scenarios.
A satellite assembly is an assembly that only contains resources. This is extremely useful for localization. Because an assembly has a culture associated, the resource manager looks for satellite assemblies containing the resources of a specific culture.
Assemblies can be viewed using the command-line utility ildasm, the MSIL disassembler. You can open an assembly by starting ildasm from the command line with the assembly as an argument or by selecting the File ~ Open menu.
it shows ildasm opening the example that you build a little later in the chapter, SharedDemo . dll. ildasm shows the manifest and the SharedDemo type in the CSharp. Assemblies . Sharing namespace. When you open the manifest, you can see the version number and the assembly attributes, as well as the referenced assemblies and their versions. You can see the MSIL code by opening the methods of the class.
In addition to using ildasm. the .NET Reflector is another great tool to use to analyze assemblies. The .NET Reflector allows type and member search, and call and caller graphs, and decompiles IL code to C#I, CH, or Visual Basic. You can download this tool from www.aisto.com/roeder /dotnet.