CHAPTER 14 BUILDING AND CONFIGURING CLASS LIBRARIES
Source Code The CustomNamespaces project is located under the Chapter 14 subdirectory.
The Role of .NET Assemblies
.NET applications are constructed by piecing together any number of assemblies. Simply put, an
assembly is a versioned, self-describing binary file hosted by the CLR. Now, despite the fact that .NET
assemblies have exactly the same file extensions (*.exe or *.dll) as previous Windows binaries, they
have very little in common with those files under the hood. Thus, to set the stage for the information to
come, let’s consider some of the benefits provided by the assembly format.
Assemblies Promote Code Reuse
As you have built your Console Applications over the previous chapters, it might have seemed that all of
the applications’ functionality was contained within the executable assembly you were constructing. In
reality, your applications were leveraging numerous types contained within the always accessible .NET
code library, mscorlib.dll (recall that the C# compiler references mscorlib.dll automatically), and in
the case of some examples, System.Core.dll.
As you might know, a code library (also termed a class library) is a *.dll that contains types
intended to be used by external applications. When you are creating executable assemblies, you will no
doubt be leveraging numerous system-supplied and custom code libraries as you create your
application. Do be aware, however, that a code library need not take a *.dll file extension. It is perfectly
possible (although not very common) for an executable assembly to make use of types defined within an
external executable file. In this light, a referenced *.exe can also be considered a code library.
Regardless of how a code library is packaged, the .NET platform allows you to reuse types in a
language-independent manner. For example, you could create a code library in C# and reuse that library
in any other .NET programming language. It is possible not only to allocate types across languages, but
also to derive from them. A base class defined in C# could be extended by a class authored in Visual
Basic. Interfaces defined in F# can be implemented by structures defined in C#, and so forth. The point
is that when you begin to break apart a single monolithic executable into numerous .NET assemblies,
you achieve a language-neutral form of code reuse.
Assemblies Establish a Type Boundary
Recall that a type’s fully qualified name is composed by prefixing the type’s namespace (e.g., System) to
its name (e.g., Console). Strictly speaking, however, the assembly in which a type resides further
establishes a type’s identity. For example, if you have two uniquely named assemblies (say, MyCars.dll
and YourCars.dll) that both define a namespace (CarLibrary) containing a class named SportsCar, they
are considered unique types in the .NET universe.
Assemblies Are Versionable Units
.NET assemblies are assigned a four-part numerical version number of the form
.... (If you do not explicitly provide a version number, the assembly is
automatically assigned a version of 1.0.0.0, given the default Visual Studio project settings.) This
number, in conjunction with an optional public key value, allows multiple versions of the same assembly
to coexist in harmony on a single machine. Formally speaking, assemblies that provide public key
510