Tuesday, June 24, 2008

Namespaces, Assemblies and Modules

Programming Language: C#, .NET in General
Type: Tutorial
Level: Beginners
Topic Category: General Programming
Main Series: Introduction to programming in C# and the .NET framework
Topic Title: .NET Namespaces, Assemblies
and Modules

All .NET PLs share the same code cycle: Code is written, parsed, compiled into a binary MS Intermediate Language (MSIL) Assembly and then executed by the Common Language Runtime (CLR).

Simply, an assembly is a compiled .NET code. The .net framework has a common intermediate language that is as close to the Assembly language as possible which all .net PLs should compile their code into. An assembly is a binary MSIL file, thus a compiled .net code.
.NET assemblies come in three forms: Windows Executable (.exe), Console Executable (.exe) or Library (.dll)

.NET assemblies contain Modules, a piece of compiled code that is not a complete assembly. This technique is primarily for development teams with more than one person working on the same assembly. Each of them can work on a different module of the assembly and the modules are merged together to form the assembly later (this way, one assembly can be developed using more than one PL, each developer accomplishes his/her work on his favorite .net language and compiles the code to a module which is then merged with the other developers' modules to form the assembly). Now, usually, an assembly will contain only one module, but for accuracy's sake, we introduced the concept of modules.

The C# PL is a fully-object-oriented language, which means in colloquial terms "everything is a class". In .net terms, this means that C# modules can only contain class definitions, nothing more. Because assemblies are the binary MSIL binary compiled version of C# code files, this means that C# code files must not contain anything other than class definitions, and that is true. However, there is two more constructs that a C# code file can contain on its root level: namespace declaration and namespace using statements. Now, these are not memory consuming instructions like variable declaration nor are they code declaration/grouping constructs like methods. Namespaces are logical grouping of classes within a scope. They can be thought of as being prefixes to the class names of all the classes declared within them. They enable developers to create classes with globally unique names and at the same time help developers organize code within categories that you specify.

Let's take a look at a namespace declaration:

namespace GUI{
namespace DrawingShapes{

class ShapeBase{}

class Rectangle : ShapeBase{}

class Circle : ShapeBase{}

....

}

namespace Controls{

class MyControlBase{}

class MyButton : MyControlBase{}

}
namespace Text{

class MyTextBox{}

class MyRichTextBox{}

}

namespace Tools{

class Tool1{}

class Tool2{}

}

namespace InternalImplementation{

}

}

As you might have noticed, this is a clipping of a graphical user interface elements library. Now imagine two companies/developers working on the same project (GUI elements library). They both choose to develop a circle class, a rectangle class and so on. However, a developer wants to use both libraries together (may be the circle of the first company is drawn better than the one from the second company!) If there was no way to distinguish each class from the beginning, it will be impossible for the developer to use both libraries.
However, as we said, a namespace is a scope of the classes defined within it and it becomes a part of its name, so now the full name of the Circle class in this example becomes: GUI.DrawingShapes.Circle
Now, if every company/developer kept all his/her classes in a parent namespace of his choosing, it becomes nearly impossible that a naming collision will occur between his/her classes and other developers' classes. It also solves naming conflicts within the same library, for example, in an engineering design application library, you might want to develop a class that will represent the geometrical shape called Rectangle, and at the same time you want to represent a screen drawn Rectangle. These are two types sharing the same name.

Assemblies:

  • Binary compiled code files
  • Contain Modules that contain classes
  • When deciding how to divide classes on assemblies, you usually want to physically separate classes in separate files (for example, dictionary classes and drawing classes in a word processing application should be physically separated because they are both optional components of the application so they might and might not be included in the installation of the application)
  • You should always separate classes in different assemblies if they are:
    • Different plug-ins/add-ins to a container application
    • Two optional separate feature of the application
    • Perform totally unrelated tasks
  • An assembly can contain classes from different namespaces
Namespaces:
  • Logical scope of classes
  • Classes from the same namespace can span multiple assemblies
  • Is used to solve naming conflicts in classes
  • Adds a prefix to the class name
  • Is used to group similar classes (usually by task)

No comments: