CCI Metadata

The CCI libraries are not associated with any particular application environment. You can use CCI, for example, to work with applications that are stored as files on a hard drive, in memory, or even in a Microsoft Word document. However, the libraries often require application-specific information such as where files are located, where to find referenced assemblies, or the targeted .NET version.

From a CCI perspective, such issues are matters of application policy. CCI queries a host object for the information, and the host handles the details and returns the results to CCI through a standard interface. For example, when CCI must locate an assembly, it calls the host’s FindAssembly method. This method locates the assembly and returns a Microsoft.Cci.IAssembly interface that represents the assembly in the CCI environment.

Default and Custom Hosts

All host objects inherit from Microsoft.Cci.MetaDataReaderHost. CCI Metadata includes a default host object, Microsoft.Cci.PeReader.DefaultHost, which provides default policy settings and is sufficient for many applications. However, some applications require non-default policy settings and must implement a custom host by implementing a class that inherits from MetaDataReaderHost and overriding the appropriate methods. The following are some examples of when you must implement a custom host.
Specify a Particular Core Assembly
DefaultHost specifies unification for mscorlib.dll, which directs .NET to use the latest version on the system. To force.NET to use a particular mscorlib.dll version, you must implement a custom host and override MetadataReaderHost.UnifyAssembly.
Obtain an Assembly from a Non-Standard Location
An application specifies an assembly’s location by passing a string to the appropriate CCI Metadata method. CCI Metadata then passes that string to the host, which must use that string obtain the assembly. DefaultHost interprets such strings as file paths, which requires the assembly to be a PE file on the hard drive. However, assemblies could be obtained from a variety of locations, such as:
  • Downloaded from a Web site. In that case, the string would be a URL, and the host would have to understand how to parse the URL and download the assembly.
  • Embedded in a Word document. In that case, the string would a file path and a moniker, and the host would have to understand how to use COM interop to extract the assembly from the file.
  • In a SQL database. In that case, the string would identify the server and include a query for the assembly.
For all these cases, you must implement a custom host and override the MetadataReaderHost.FindAssembly method so that it interprets the string correctly and takes appropriate action.

Multiple Host Objects

Most applications use a single host object. However, there are some cases where you must use multiple hosts. For example, the CCI metadata libraries depend on the host for a reference to mscorlib.dll. However, a host can hold a reference to only one mscorlib.dll version. If you want to compare metadata from different mscorlib versions, you must use a separate host for each version.

Hosts and Name Tables

A host must have a NameTable object. If your application has only one host, you can use the default constructor, which creates a new NameTable object and assigns it to the host object’s NameTable property. You can then use that object in the remainder of the application. The following example from the HelloIL sample creates a new DefaultHost object by using the default constructor.
MetadataReaderHost host = new PeReader.DefaultHost();
NameTable nameTable = host.NameTable;

If an application has multiple hosts, they normally use the same NameTable object, which ensures that every host uses the same string-to-key mappings. Before you create the first host object, explicitly create a NameTable object and then pass it to each host when you create the host object. The host then uses that NameTable object rather than creating one. For example:
NameTable nameTable = new NameTable();
MetadataReaderHost host1 = new PeReader.DefaultHost(nameTable);
MetadataReaderHost host2 = new PeReader.DefaultHost(nameTable);

Last edited Dec 17, 2009 at 10:22 PM by Guy_Smith, version 1


No comments yet.