Understanding C#: Namespaces and assemblies (a quick .NET tutorial)

By Andrew Stellman
July 12, 2010 | Comments: 4

I recently had a reader e-mail me with a question about assemblies and namespaces because he had trouble on a job interview that asked a lot of interview questions about .NET assemblies. Luckily, I had a good answer for him that covered the .NET assembly basics: what an assembly is, how to create a class assembly DLL, how to use that assembly DLL in another program, how to use the Add References window in Visual Studio, and where Visual Studio gets its assemblies to list in that window.

Head First C# Cover

At the end of Head First C#, we have a section about it that also uses the IDE as a teaching tool to explore how assemblies work. I thought it did a good job of answering that reader's .NET assembly interview questions, and I hope it will help some others get a handle on how namespaces and assemblies work. It makes for a good .NET assembly tutorial that shows the basics of assemblies work in C# programs. So here it is, adapted to blog post format.

Note: The section at the end of the book is called "Leftovers", and this is leftover #2, so that's why I used a namespace called Headfirst.Csharp.Leftover2.

When you compile your C# program, you're creating an assembly. An assembly is a file that contains the compiled code. There are two kinds of assemblies. Executables (occasionally called "process assemblies") have the EXE file extension. All of the programs in our book are compiled as executables. Those are the assemblies that you can execute (you know, EXE files you can double-click and run). There are also library assemblies, which have the DLL file extension. They're often referred to as class libraries because they contain classes that you can use in your programs. And as you'll see shortly, namespaces play a big role in how you use them.

An easy way to create a library assembly is to create a Class Library project in Visual Studio by choosing "Class Library" as the project type when you create a new project. You're probably used to creating Windows Forms Applications, WPF Applications, or Console Applications by choosing the appropriate icon from the New Project window in Visual Studio. This time you'll use the Class Library icon. That's where we'll start the .NET assembly walkthrough.

Create a class library assembly and use it in an application

You can get a handle on the basics of assemblies by first creating a class library, and then building a program that uses it. Start by opening up Visual Studio and creating a new Class Library project called Headfirst.Csharp.Leftover2. When the library is first created, it contains the file Class.cs. Delete that file and add a new class called Guy.cs by right-clicking on the project in the Solution Explorer and selecting "Class..." from the Add menu. Open up the new Guy.cs file:

namespace Headfirst.Csharp.Leftover2
{
     class Guy
     {
     }
}

Notice how Visual Studio made the namespace match your class library name? That's a very standard pattern.

Go ahead and fill in the Guy class -- if you've read my other "Understanding C#" posts, it's the same one you've used before. It's the same class from my post about XML Comments. You can find the source to the Guy class here.

Next, add two more classes called HiThereWriter and LineWriter. Here's the code for HiThereWriter:

namespace Headfirst.Csharp.Leftover2
{
     public static class HiThereWriter
     {
        public static void HiThere(string name)
         {
             MessageBox.Show("Hi there! My name is " + name);
         }
     }
}

And here's the code for LineWriter (it's also in the Headfirst.Csharp.Leftover2 namespace):

internal static class LineWriter {
     public static void WriteALine(string message)
     {
          Console.WriteLine(message);
     }
}
Note: I named the class library Headfirst.Csharp.Leftover2 because that's a pretty standard way of naming assemblies. You can read more about how to name your .NET assemblies and assembly naming conventions here: http://msdn.microsoft.com/en-us/library/ms229048.aspx.

Now try to compile your program. You'll get an error:

Screenshot - MessageBox does not exist error.png

If you're a Head First C# reader, you've seen that error before -- The name 'MessageBox' does not exist in the current context -- but if not, no problem. We know how to fix this. Add a line to the top of your class:

using System.Windows.Forms;

Wait, it still doesn't compile! That usually fixes the problem. At least, it does in Windows Forms Applications programs. And something's weird here. When you typed in that line, did you notice that when you got as far as "using System.Win" the IntelliSense window stopped giving you suggestions? That's because your project hasn't referenced the System.Windows.Forms assembly.

Let's fix this by referencing the correct assembly. Go to the Solution Explorer and expand the "References" folder in your project. Right-click on it and choose "Add Reference..."; a window should pop up:

Screenshot - Add Reference System.Windows.Forms.png

This window is showing you the assemblies your program can access. Some of them are stored in the Global Assembly Cache (GAC), but not every assembly in the GAC shows up in this window. The GAC is a central, machine-wide set of assemblies that all of the .NET programs on the computer can access. You can see all of the assemblies in it by typing %systemroot%\assembly into the Start menu (or Start/Run for older versions of Windows). Take a minute and do this now. Notice how there are many different versions of some assemblies? Your programs can reference a specific assembly version, so they won't break even if a newer, incompatible version gets installed on the computer.

On the .NET tab, start typing "System.Windows.Forms"--it should jump down to that assembly. Make sure it's highlighted and click OK. Now System.Windows.Forms should show up under the References folder in the Solution Explorer--and your program compiles!

Note: The "Add References" window figures out which assemblies to display by checking a registry key, not the GAC. For more info, see: http://support.microsoft.com/kb/306149

... so what did I just do?

Take a close look at the declarations for LineWriter and HiThereWriter:

    public class HiThereWriter
    internal static class LineWriter

There are access modifiers on the class declarations: HiThereWriter is declared with the public access modifier, and LineWriter is declared with the internal one. In a minute, you'll write a console application that references this class library. A program can only directly access another class library's public classes--although they can be accessed indirectly, like when one method calls another or returns an instance of an internal object that implements a public interface.

Now go back to your Guy class and look at its declaration:

     class Guy

Since there's no access modifier, it defaults to internal. We'll want to declare a Guy from another class, so change the declaration to be public:

    public class Guy

Next, try running your program in the debugger. You'll see this error:

Screenshot - Error starting class library.png

Think about what that error says: A project with an output type of Class Library cannot be started directly. That actually makes sense when you think about it, because a class library doesn't have an entry point. It's just a bunch of classes that other programs can use. So let's add an executable program that uses those classes--that way the debugger has something to run. Visual Studio has a really useful feature that we'll take advantage of next: it can load multiple projects into a single solution. Right-click on the Solution Explorer and choose Add >> New Project... to bring up the usual Add Project window. Add a new console application called MyProgram.

Once your new program's added, it should appear in the Solution Explorer right under the class library. Right-click on References underneath MyProgram, and choose "Add reference..." from the menu. This time, open the Projects tab. You should see your class library project listed--select it and click OK. It should now appear in the References window.

Go to the top of your new project's Program.cs file and start adding this using line:

    using Headfirst.Csharp.Leftover2;

Notice how the IntelliSense picks up "Csharp" and "Leftover2" as you're typing?

Now we can write a new program. Start by typing Guy and Watch what pops up. As soon as you type it, you should see this IntelliSense window:

Screenshot - IntelliSense from another assembly.png

The IntelliSense window lists the entire namespace for Guy, so you can see that you're actually using the class that you defined in the other assembly. Finish the program:

static void Main(string[] args)
{
     Guy guy = new Guy("Joe", 43, 125);
     HiThereWriter.HiThere(guy.Name);
}

Now run your program. Oh, wait--you get the same error message as before, because you can't run a class library! No problem. Right-click on your new MyProgram project in the Solution Explorer and choose "Set as Startup Project". Your solution can have many different projects, and this is how you tell it which one to start when you run it in the debugger. Now run your program again--this time it runs!

This post just scratches the surface of assemblies. There's a lot more (including versioning and signing them for security). You can read more about assemblies here: http://msdn.microsoft.com/en-us/library/k3677y81.aspx

Andrew Stellman is the author of Head First C# and other books from O'Reilly. You can read more from Andrew at Building Better Software.


You might also be interested in:

4 Comments

PERFECT ! THANK YOU SO SO MUCH !!

hi this is sathish ...this information is very useful for me.......


thank you very much.............

thanks alot my friend!it was really a complete refersnce about what i want!

Hi.. I have done exactly as said but in the project i am not able to use the
namespace : - using Headfirst.Csharp.Leftover2;

intellisense is not picking up the namespace in the project created to test the namespace

Please advice.

News Topics

Recommended for You

Got a Question?