This article is the second part of a three-part series of articles covering the .Net assemblies. In Part 1, I covered what exactly an assembly is, and what an assembly contains. In this article, Part 2 of the series I will discuss both Private and Shared assemblies and how to create a "Shared Assembly". It is assumed that you are already familiar with creating apps or dll files. I will briefly mention some of the utilities available for working with assemblies. Part 3 will discuss in more detail than Part 2, the details of the available utilities for manipulating assemblies.

Assembly Accessibility

There are two types of assemblies when referring to accessibility: Private and Shared.

Why create a shared assembly?

The following are some reasons why you may want to create a shared assembly:

Creating a Private Assembly

As mentioned earlier, the default access for an assembly is private. Unless you take measures to create a shared assembly, when you compile your application using the SDK-supplied compiler vbc.exe, a private assembly is created with the proper manifest information. This happens via the command line or by building from within Visual Studio. NET. Compiling some code as follows:

Bbc HelloWorld.vb

produces the application/private assembly

HelloWorld.exe

Creating a Shared Assembly

Creating a shared assembly is a little more involved. Microsoft has supplied all the tools needed to perform this task. The first item we will need is an assembly compiled in the normal way. We will create a module for this called Hello.dll that contains the following code:

namespace hello {
    using System;

    public class Class1 {
        public Class1() { }

        public void SayHello(string name) {
            Console.WriteLine("Hello " + name);
        }
    }
}

The first tool required is the "Strong Name" utility. Your SDK should contain a file named: sn.exe. Running the Strong Name utility will provide you with a file containing the public and private keys to use. These keys will later be used to give our assembly the guaranteed unique name. From the command line run the following command:

Sn -k myKeys.sink

The Strong Name utility will generate a file called myKeys. sink, where the sink extension stands for "strong name key". The -k designates the output file, that we have named myKeys.snk in this example. There are other switches that we will discuss in Part 3.

If you did not run the command from your project folder, then copy the file that was just created to your project folder.

Signing the Assembly

Now we have the keys but we still need to tell our program to use a key. Adding the key to the assembly is referred to as "signing" the assembly. To do this we need to open a file that is located in your project folder called AssemblyInfo.vb In Visual Studio .NET you can look in the Solution Explorer under the project node. Right-click on the AssemblyInfo file and select Open. If you are not using Visual Studio then any text editor should work. Scroll down toward the end of the file and look for the following line:

[assembly: AssemblyKeyFile("")]

Edit the file and place the name of your key file between the quotes in the parentheses. The line in your AssemblyInfo.vb file should now look like this:

[assembly: AssemblyKeyFile("myKeys.snk")]

We have now told the compiler to use our keys to digitally sign the assembly, thus creating a guaranteed unique namespace. However, you must re-compile the code in order to complete the process. Compile the program with the edited version of the AssemblyInfo.vb file.

Important: In order for the assembly to use your private signature (key file), you must recompile your program.

Sharing Your Code

In order for your code to be shared with other assemblies, you need to place your newly signed, shared assembly in the global section of the Assembly Cache. Unfortunately, you cannot just copy your code over to the global cache folder. You need to run another command-line utility that Microsoft has supplied called Assembly Linker. In your SDK should be a file named AL.exe.

The Assembly Linker will create the proper folder in the Global Assembly Cache. This folder's name will contain part of the assembly's unique identity. To run the AL program, go to a command line (make sure the current folder is the same folder your hello.dll file is in) and type in the following command:

AL /install:Hello.dll

The preceding command can also be shortened to AL /i:Hello.dll.

The Assembly Linker program has other uses that I will mention in Part 3 of this article series.

Now if you look in your Global Assembly Cache you should see a new folder where your assembly was placed for sharing. My system placed the assembly at:

C:\Windows\assembly\global\T2\LGRE\hello.dll

Your system will use something slightly different. Now we're ready to test the assembly to see if we can access the SayHello() method.

Using the Shared Assembly

Now let's create a small program that will call the SayHello() method that resides in our shared assembly. When you compile this program you will need to set a reference to the originally shared assembly. Make sure that the reference path points to where the hello.dll file resides and not the current project path.

namespace myHello {
    using System;
    using hello;

    public class HelloClass {
        public HelloClass() { }

        public static int Main(string[] args) {
            Class1 speak = new Class1();
            speak.SayHello("John");
            return 0;
        }
    }
}

After you compile the program you can place the myHello.exe file almost anywhere in your system's file path and it will locate the shared assembly hello.dll when you run the application. When you run the myHello.exe application the result will be:

Hello John

This works because the runtime will check specific search paths starting with the application's base path, and eventually the Assembly Cache. If we had not created the hello.dll as a shared assembly and then tried to run the application without the hello.dll in the applications base folder, then we would have received an error such as:

Exception occurred: System.TypeLoadException: Could not load class "Class1"...

Using shared assemblies can allow you to reuse code, maintain a unique

namespace, and maintain versioning.

Continue Reading