Self-Examination: Contemplating Our Own Assembly

Self-Examination: Contemplating Our Own Assembly

Now, what fun would it be if we didn't use this program to examine the assembly we just created? Select Build | Build to create AssemblySpy.exe in the bin directory of your project. Run the program, navigate to the bin folder and load your new assembly in Assembly Spy. The filename of the assembly is AssemblySpy. The program has a namespace, AssemblyView, and within that namespace we have a single class, AssemblySpyForm.

Namespace AssemblyView Public Class AssemblySpyForm

In the list box, as shown in Figure 8-15, we see our fully qualified namespace, <Assembly> <NameSpace> <Class within the namespace>. Clicking the list box reveals the current class within the namespace, AssemblySpyForm. When the categories are expanded, we can see our constant program name, progName, under the Static Fields category. We can also poke around and see the various variables, such as tnNode and tnRootNode. Very self-referential, eh?

Figure 8-15

Looking at our own assembly in the Assembly Spy program.

In the following sections, we'll use our own assembly to add to our understanding of some of the concepts that I touched on briefly earlier in the chapter. I'll cover code signing and strong names and then return to the global assembly cache. You'll learn how to provide an assembly with a strong name, register it in the global assembly cache, and administer how it can be used.

Code Signing

Remember that when you distribute your .NET component or program, you'll want to assure your users that you are the author, that the code is safe and can be trusted, and that the identity of the assembly can be verified. You accomplish these guarantees by signing your code. You can sign an assembly in two ways.

The first way is to use a digital certificate, also called signcode. To sign your assembly using signcode, you go to a third-party authority and prove your identity. At that time you obtain a digital certificate that guarantees you are the originator of the component. All secure Web sites use a digital certificate to ensure visitors that they are connecting to the site they think they're connecting to. Likewise, you can sign your program or component to ensure that you are the author.

Another way to sign your code is to assign your assembly a strong name. As I described earlier in the chapter, a strong name consists of the assembly's identity plus a public key and a digital signature. A strong name is guaranteed to be a unique name, and thereby ensures the identity of your assembly. Although providing a strong name for your assembly guarantees its identity, it by no means guarantees that the code can be trusted. Put another way, a strong name uniquely identifies and guarantees the identity of an assembly, but it does not guarantee that you wrote it. However, a trust decision can reasonably be made on the basis of a strong-name identity alone. If you are selling or distributing components in the wild, you will want to look into getting a digital certificate.

Creating a Strongly Named Assembly

When you build an assembly as we just did, it is not strongly named by default. To sign an assembly with a strong name, you must have a public-private key pair. These public and private keys are a cryptographic key pair that's used during compilation to create the strong name for an assembly. You create a key pair using the Strong Name tool (Sn.exe). Key pair files usually have an .snk file extension. We'll put Sn.exe to work shortly.

The StrongName class represents evidence of a unique, cryptographically strong name of a code assembly. The strong name consists of a public key, a given name, and version parts. The public key corresponds to the publisher's private key, which is kept secret and with which the assembly must be signed in order for the strong name to be valid.

Let's take a few minutes and create a strong name for our assembly.

  1. Right-click Form1.vb in the Solution Explorer and rename the form file AssemblySpyForm.vb, as shown in Figure 8-16.

    Figure 8-16

    Use the Solution Explorer to rename the form file AssemblySpyForm.vb.

  2. Open the AssemblyInfo.vb file. Notice that it includes general information about various attributes of the assembly. Add the title, description, and a fictitious company name if you want.

Notice that the assembly also contains a globally unique ID, or GUID, that is used to register your program in the Windows registry if it interacts with COM.

Imports System.Reflection Imports System.Runtime.InteropServices ' General information about an assembly is controlled through ' the following set of attributes. Change these attribute values ' to modify the information associated with an assembly. ' Review the values of the assembly attributes. <Assembly: AssemblyTitle("Assembly Spy")> <Assembly: AssemblyDescription("Examine Assemblies")> <Assembly: AssemblyCompany("Solidstate Software, Inc.")> <Assembly: AssemblyProduct("")> <Assembly: AssemblyCopyright("2001")> <Assembly: AssemblyTrademark("")> <Assembly: CLSCompliant(True)> ' The following GUID is for the ID of the typelib if this ' project is exposed to COM <Assembly: Guid("FB159EAB-6F6C-4661-AA62-86442266C725")> ' Version information for an assembly consists of the following ' four values: ' ' Major Version ' Minor Version ' Build Number ' Revision ' ' You can specify all the values or you can default the Build ' and Revision Numbers ' by using the '*' as shown below: <Assembly: AssemblyVersion("1.0.*")> 

Now that we have updated our metadata, let's add a strong name. You can give an assembly a strong name by using a command line program. First you use the Sn.exe utility to generate a public and private key pair. Next we indicate to our assembly where the key file is located, and then rebuild the assembly.

  1. Locate Sn.exe on your drive. You use the command parameters sn –k <file name> to create a key pair. We'll name our key file asKey.snk.

  2. At the command prompt, type sn –k asKey.snk. You will see the following message on your screen:

    Microsoft (R) .NET Framework Strong Name Utility Version 1.0.2914.11

    Copyright (C) Microsoft Corp. 1998-2001. All rights reserved.

    Key pair written to asKey.snk

  3. We want to add the key file we just generated, so you have to open AssemblyInfo.vb and add the AssemblyKeyFile command yourself. Pass in the fully qualified path to the file you just created with the key pair, as shown here.

    Imports System.Reflection Imports System.Runtime.InteropServices ' General information about an assembly is controlled ' through the following set of attributes. Change these ' attribute values to modify the information associated ' with an assembly. ' Review the values of the assembly attributes. <Assembly: AssemblyTitle("Assembly Spy")> <Assembly: AssemblyDescription("Examine Assemblies")> <Assembly: AssemblyCompany("Solidstate Software, Inc.")> <Assembly: AssemblyProduct("")> <Assembly: AssemblyCopyright("2001")> <Assembly: AssemblyTrademark("")> <Assembly: CLSCompliant(True)> <Assembly: AssemblyKeyFile("C:\VB .NET Coding Techniques \Chap08\AssemblySpy\asKey.snk")> ' The following GUID is for the ID of the typelib if this ' project is exposed to COM <Assembly: Guid("FB159EAB-6F6C-4661-AA62-86442266C725")> ' Version information for an assembly consists of the follow- ' ing four values: ' ' Major Version ' Minor Version ' Build Number ' Revision ' ' You can specify all the values or you can default the ' Build and Revision Numbers ' by using the '*' as shown below: <Assembly: AssemblyVersion("1.0.*")> 

  4. Rebuild your project by clicking Build | Rebuild Solution. That's it!

The Global Assembly Cache Revisited

Earlier in the chapter we looked at the mscorcfg.msc program, which permits us to examine the global assembly cache. If we attempt to add an assembly that does not have a strong name to the global cache, it will bark at us, as you can see in Figure 8-17.

Figure 8-17

You can't add an assembly that doesn't have a strong name to the global assembly cache.

However, now that our AssemblySpy assembly has a strong name, we can click the Assembly Cache to give it focus and click Action | Add, navigate to the directory that contains our assembly, and then add our assembly to the global cache. Figure 8-18 shows that our assembly now has a public key token that is the hexidecimal representation of the public key that is the cryptographic public key for the assembly. Cool. (If no culture is defined, such as English or French or Chinese, the Locale is neutral.)

Figure 8-18

Our assembly is now part of the global cache.

Use Windows Explorer to navigate to the folder where your program is located, right-click the program, and select Properties. As you can see in Figure 8-19, the General tab lists information about the program. Notice that our AssemblySpy program is under 20,000 bytes. The compiler does a good job at providing trim, streamlined programs. Because our assembly relies on the .NET Framework, our programs are reasonably small because most of the code is shared from framework assemblies in the global assembly cache.

Figure 8-19

The General tab.

On the Version tab, shown in Figure 8-20, you can see that the information we placed in the AssemblyInfo.vb module can be viewed by the public. Simply add any legal trademarks or other identifying information, and the information will be readily available when you distribute your assembly.

Figure 8-20

The Version tab.

Assembly Versioning

Microsoft recommends that programmers avoid sharing assemblies if at all possible. Also, you should get into the habit of providing even your private assemblies with strong names. And, once an application is deployed, you should resist the temptation to update an assembly file. Sometimes, however, a bug is discovered (gasp!), and something must be done. In situations such as this, assembly versioning comes into play.

Remember that in our assembly file in the Solution Explorer we had this line.

<Assembly: AssemblyVersion("1.0.*")>

When you need to modify or otherwise update a deployed assembly, you should update the version before you recompile. Every assembly has a version number associated with it. An assembly's version consists of information such as the following:

Assembly Version Major Number

Assembly Version Minor Number

Build Number

Revision Number

1

5

432

2

Using the sample values, we have an assembly with the version number 1.5.432.2. The first two numbers, 1.5, make up the logical assembly version. The third number, 432, represents the build number of the assembly. If you rebuild your assembly each day, this number should be incremented appropriately. The last number, 2, represents the revision of the current build.

The common language runtime considers assemblies with different versions to be different assemblies even though several assemblies with the same name might exist. How the runtime understands assemblies can have some unpleasant consequences. Let's say that a Visual Basic .NET program is compiled with version 1.5.432.2 of your assembly, but this version has been deleted from the global assembly cache. Only version 2.0.0.0 is available. When the program that was compiled with the earlier version is run, the CLR will not bind with the new version of the assembly and the program will fail. (This behavior is how binding occurs by default. Binding can be changed using an administrative override.)

If the runtime sees two assemblies with the same name and the same major and minor versions, it will attempt to bind to the assembly with the latest build and revision numbers.

note

Versioning applies only to strongly named global assemblies. When using a private assembly, the runtime will use whichever assembly it can find. The version information is not used.

Load the .NET Admin Tool mscorcfg.msc once again. Click Configured Assemblies, and then click Configure An Assembly on the right. The Configure An Assembly dialog box, shown in Figure 8-21, is displayed.

Figure 8-21

The Configure An Assembly dialog box.

Click the Choose Assembly button to display the Choose Assembly From Assembly Cache dialog box, shown in Figure 8-22. Select AssemblySpy, click Select, and then click Finish in the Configure An Assembly dialog box.

When you click Finish, the AssemblySpy Properties dialog box is displayed, shown in Figure 8-23. The first tab shows the name of our assembly and the public key token. To conserve storage space, the CLR hashes the full public key and takes the last eight bytes of the hashed value. This reduced value has been statistically determined to be unique, so it is safe to use. The reduced value of the public key is called the public key token and is stored in the AssemblyRef table mentioned earlier.

Figure 8-22

The Choose Assembly From Assembly Cache dialog box.

Figure 8-23

The Assembly Spy program properties dialog box.

The second tab, Binding Policy, shown in Figure 8-24, provides options for an administrator to tell the runtime how to bind to assemblies with newer version numbers. These settings let you administer exactly how the runtime uses various versions of the assembly.

Figure 8-24

The Binding Policy tab provides options for overriding the default binding behavior.



Coding Techniques for Microsoft Visual Basic. NET
Coding Techniques for Microsoft Visual Basic .NET
ISBN: 0735612544
EAN: 2147483647
Year: 2002
Pages: 123
Authors: John Connell

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