1. public key token is the last 8 bytes of public key which has been hashed.
2.The public key field in AssemblyDef metadata table stores the full public key.
The public key filed in AssemblyRef metadata table stores the public key token.
3. Whenever you build an assembly, the assembly will have references to other strongly named
assemblies. This is true because System.Object is defined in MSCorLib.dll, which is strongly
named. However, it’s likely that an assembly will reference types in other strongly named assemblies
published either by Microsoft, a third party, or your own organization. In Chapter 2,
I showed you how to use CSC.exe’s /reference compiler switch to specify the assembly file
names you want to reference. If the file name is a full path, CSC.exe loads the specified file
and uses its metadata information to build the assembly. As mentioned in Chapter 2, if you
specify a file name without a path, CSC.exe attempts to find the assembly by looking in the
following directories (in order of their presentation here):
1)Working directory.
2)The directory that contains the CSC.exe file itself. This directory also contains the CLR
DLLs.
3) Any directories specified using the /lib compiler switch.
4)Any directories specified using the LIB environment variable.
So if you’re building an assembly that references Microsoft’s System.Drawing.dll, you can
specify the /reference:System.Drawing.dll switch when invoking CSC.exe. The compiler
will examine the directories shown earlier and will find the System.Drawing.dll file in the
directory that contains the CSC.exe file itself, which is the same directory that contains the
DLLs for the version of the CLR the compiler is tied to. Even though this is the directory
where the assembly is found at compile time, this isn’t the directory where the assembly will
be loaded from at runtime.
4. <?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="AuxFiles;bin/subdir" />
<dependentAssembly>
<assemblyIdentity name="JeffTypes"
publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/>
<bindingRedirect
oldVersion="1.0.0.0" newVersion="2.0.0.0" />
<codeBase version="2.0.0.0"
href="http://www.Wintellect.com/JeffTypes.dll " />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="TypeLib"
publicKeyToken="1f2e74e897abbcfe" culture="neutral"/>
<bindingRedirect
oldVersion="3.0.0.0-3.5.0.0" newVersion="4.0.0.0" />
<publisherPolicy apply="no" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
This XML file gives a wealth of information to the CLR. Here’s what it says:
n probing element Look in the application base directory’s AuxFiles and bin/subdir
subdirectories when trying to find a weakly named assembly. For strongly named assemblies,
the CLR looks in the GAC or in the URL specified by the codeBase element.
The CLR looks in the application’s private paths for a strongly named assembly only if
no codeBase element is specified.
n First dependentAssembly, assemblyIdentity, and bindingRedirect elements
When attempting to locate version 1.0.0.0 of the culture-neutral JeffTypes assembly
published by the organization that controls the 32ab4ba45e0a69a1 public key token,
locate version 2.0.0.0 of the same assembly instead.
n codeBase element When attempting to locate version 2.0.0.0 of the culture-neutral
JeffTypes assembly published by the organization that controls the 32ab4ba45e0a69a1
public key token, try to find it at the following URL: www.Wintellect.com/JeffTypes.dll .
Although I didn’t mention it in Chapter 2, a codeBase element can also be used with
weakly named assemblies. In this case, the assembly’s version number is ignored and
should be omitted from the XML’s
codeBase element. Also, the codeBase URL must
refer to a directory under the application’s base directory.
n
Second dependentAssembly , assemblyIdentity , and bindingRedirect
elements
When attempting to locate version 3.0.0.0 through version 3.5.0.0 inclusive of the
culture-neutral TypeLib assembly published by the organization that controls the
1f2e74e897abbcfe public key token, locate version 4.0.0.0 of the same assembly instead.
n
publisherPolicy element
If the organization that produces the TypeLib assembly
has deployed a publisher policy file (described in the next section), the CLR should
ignore this file.
When compiling a method, the CLR determines the types and members being referenced.
Using this information, the runtime determines, by looking in the referencing assembly’s
AssemblyRef table, the assembly that was originally referenced when the calling assembly
was built. The CLR then looks up the assembly/version in the application’s configuration
file and applies any version number redirections; the CLR is now looking for this assembly/
version.
If the
publisherPolicy element’s apply attribute is set to yes
—or if the element is omitted
—the CLR examines the GAC for the new assembly/version and applies any version number
redirections that the publisher of the assembly feels is necessary; the CLR is now looking for
this assembly/version. I’ll talk more about publisher policy in the next section. Finally, the CLR
looks up the new assembly/version in the machine’s Machine.config file and applies any
version number redirections there.
At this point, the CLR knows the version of the assembly that it should load, and it attempts
to load the assembly from the GAC. If the assembly isn’t in the GAC, and if there is no
codeBase
element, the CLR probes for the assembly as I described in Chapter 2. If the configuration
file that performs the last redirection also contains a
codeBase
element, the CLR
attempts to load the assembly from the
codeBase
element’s specified URL.
If the new assembly doesn’t fix the original bug, the administrator can delete the binding
redirection lines from the configuration file, and the application will behave as it did before.
It’s important to note that the system allows the use of an assembly that doesn’t exactly
match the assembly version recorded in the metadata. This extra flexibility is very handy.
Publisher Policy Control
In the scenario described in the previous section, the publisher of an assembly simply sent a
new version of the assembly to the administrator, who installed the assembly and manually
edited the application’s or machine’s XML configuration files. In general, when a publisher
fixes a bug in an assembly, the publisher would like an easy way to package and distribute
the new assembly to all of the users. But the publisher also needs a way to tell each user’s
CLR to use the new assembly version instead of the old assembly version. Sure, each user
could modify his or her application’s or machine’s XML configuration file, but this is terribly
inconvenient and error prone. What the publisher needs is a way to create policy information
that is installed on the user’s computer when the new assembly is installed. In this section, I’ll
show how an assembly’s publisher can create this policy information.
Let’s say that you’re a publisher of an assembly and that you’ve just created a new version
of your assembly that fixes some bugs. When you package your new assembly to send out
to all of your users, you should also create an XML configuration file. This configuration file
looks just like the configuration files we’ve been talking about. Here’s an example file (called
JeffTypes.config) for the JeffTypes.dll assembly:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="JeffTypes"
publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/>
<bindingRedirect
oldVersion="1.0.0.0" newVersion="2.0.0.0" />
<codeBase version="2.0.0.0"
href="http://www.Wintellect.com/JeffTypes.dll"/ >
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Of course, publishers can set policies only for the assemblies that they themselves create. In
addition, the elements shown here are the only elements that can be specified in a publisher
policy configuration file; you can’t specify the probing or publisherPolicy elements, for
example.
This configuration file tells the CLR to load version 2.0.0.0 of the JeffTypes assembly whenever
version 1.0.0.0 of the assembly is referenced. Now you, the publisher, can create an assembly
that contains this publisher policy configuration file. You create the publisher policy
assembly by running AL.exe as follows:
AL.exe /out:Policy.1.0.JeffTypes.dll
/version:1.0.0.0
/keyfile:MyCompany.snk
/linkresource:JeffTypes.config
Let me explain the meaning of AL.exe抯 command-line switches:
n /out This switch tells AL.exe to create a new PE file, called Policy.1.0.JeffTypes.dll,
which contains nothing but a manifest. The name of this assembly is very important.
The first part of the name, Policy, tells the CLR that this assembly contains publisher
policy information. The second and third parts of the name, 1.0, tell the CLR that this
publisher policy assembly is for any version of the JeffTypes assembly that has a major
and minor version of 1.0. Publisher policies apply to the major and minor version numbers
of an assembly only; you can抰 create a publisher policy that is specific to individual
builds or revisions of an assembly. The fourth part of the name, JeffTypes, indicates the
name of the assembly that this publisher policy corresponds to. The fifth and last part
of the name, dll, is simply the extension given to the resulting assembly file.
n /version This switch identifies the version of the publisher policy assembly; this
version number has nothing to do with the JeffTypes assembly itself. You see, publisher
policy assemblies can also be versioned. Today, the publisher might create a publisher
policy redirecting version 1.0.0.0 of JeffTypes to version 2.0.0.0. In the future, the publisher
might want to direct version 1.0.0.0 of JeffTypes to version 2.5.0.0. The CLR uses
this version number so that it knows to pick up the latest version of the publisher policy
assembly.
n /keyfile This switch causes AL.exe to sign the publisher policy assembly by using
the publisher抯 public/private key pair. This key pair must also match the key pair used
for all versions of the JeffTypes assembly. After all, this is how the CLR knows that the
same publisher created both the JeffTypes assembly and this publisher policy file.
n /linkresource This switch tells AL.exe that the XML configuration file is to be
considered a separate file of the assembly. The resulting assembly consists of two files,
both of which must be packaged and deployed to the users along with the new version
of the JeffTypes assembly. By the way, you can抰 use AL.exe抯 /embedresource switch to
embed the XML configuration file into the assembly file, making a single file assembly,
because the CLR requires the XML file to be contained in its own separate file.
Once this publisher policy assembly is built, it can be packaged together with the new
JeffTypes.dll assembly file and deployed to users. The publisher policy assembly must be installed
into the GAC. Although the JeffTypes assembly can also be installed into the GAC, it
doesn’t have to be. It could be deployed into an application’s base directory or some other
directory identified by a codeBase URL.
I want to make one last point about publisher policy. Say that a publisher distributes a publisher
policy assembly, and for some reason, the new assembly introduces more bugs than
it fixes. If this happens, the administrator would like to tell the CLR to ignore the publisher
policy assembly. To have the runtime do this, the administrator can edit the application’s
configuration file and add the following publisherPolicy element:
<publisherPolicy apply="no"/>
This element can be placed as a child element of the <assemblyBinding> element in the
application’s configuration file so that it applies to all assemblies, or as a child element of the
<dependantAssembly> element in the application’s configuration file to have it apply to a
specific assembly. When the CLR processes the application’s configuration file, it will see that
the GAC shouldn’t be examined for the publisher policy assembly. So the CLR will continue to
operate using the older version of the assembly. Note, however, that the CLR will still examine
and apply any policy specified in the Machine.config file.