I'm still sorting through replies to my call for real-world .NET applications. (If you've got more, email them to me and add to the pile.) While I'm doing that, let's take a look at how .NET applications organize the code they use. Logically, the .NET organizational unit (OU) is the namespace. Physically, the OU is the assembly.
Let's start with assemblies. I touched on the assembly concept in a previous column. An assembly is a collection of types and resources, typically stored as a single .exe or .dll file. (Technically, an assembly can span more than one file, but most assemblies don't.) All types in the .NET Framework must exist in assemblies; the Common Language Runtime (CLR) doesn't support types outside of assemblies. Also, all the types defined in a single assembly are unique to that assembly; a type can have the same name as another type, but if those types are in different assemblies, they're not the same. Each time you create any kind of application or service with Visual Basic .NET, you're building an assembly. Assemblies can be static or dynamic.
An assembly isn't just a file with executable code, however: It's also the tool you use to establish security, type identity, reference, version, and deployment boundaries for the application. The assembly's manifest stores all this information.
The security boundaries in the manifest specify the (optional) rules under which an assembly can run. By default, assemblies aren't secured, but the .NET Framework supports two mechanisms for assembly security. First, signing an assembly with a strong name adds public key encryption to the assembly, which lets you make sure that the code is what you think it is and hasn't been replaced by another assembly with the same name. Second, you can protect an assembly with certificates, which gives you a greater degree of granularity over the security associated with the assembly. For example, a security policy for a particular secured assembly might let the assembly execute but not write to the hard disk.
To avoid name confusion, the type identity information associates a particular type's name with the assembly it belongs to. Think of the type name as the type's first name and the assembly name as the type's surname, which distinguishes it from other types with the same first name.
The reference scope information helps the assembly find types and resources outside the assembly and lists any other assemblies that the current one depends on. The version information describes any version dependencies for the assembly. The default settings for the version information ensure that the .NET application attempts to run only by using the files that it has been tested with, thus avoiding DLL mismatches.
Finally, the deployment information helps the application to be as thin as possible by downloading from the server only the components that the application needs to start. This setup is equivalent to your favorite word processor starting with only the pieces it needs to display and accept text, delaying loading a spell checker until you request that tool.
I've given you a high-level view of assemblies and the role of the manifest, and I'll refer to this information in future columns. Those columns will explore these functions in more detail.