Assembly is a complex concept, a main unit of the .NET. There are many different aspects of the assemblies and their identities. If could be a subject of really big article. You can start reading here:
http://msdn.microsoft.com/en-us/library/hk5f40ct(v=VS.90).aspx[
^].
I will only explain relationships between assembly and executable module. An EXE or DLL file are kinds of assembly executable modules. First surprising fact it:
in .NET, there is no conceptual difference between DLL and EXE files.
Usually people know that EXE file is used to start a
process from OS (normally, the Shell, but any process can start any other process; one special case is Service Controller use to start any application working as a Windows Service). DLL's are used as
class libraries. When a DLL is used as a main assembly
module (see below), it can be
referenced by other assembly, a DLL or EXE. In this way, a running process have one or more assemblies loaded, directly or indirectly. A running code can also load assembly dynamically, using
System.Reflection.Assembly
.
Now, this picture is typical but not mandatory. First, any executable module can have any arbitrary "extension" (actually NTFS does not have extensions (DOS had them), so this is a legace concept now understood as a part on file name). Actually, EXE file is exactly same thing as a class library normally represented by DLLs. There is only one simple convention: one class in EXE is special: it provides the class with static
entry point method. Normally, this static method is called
Main
, but it can be anything else and can be altered in a compilation parameter.
The OS (.NET Framework) simply "knows" by convention that an assembly should be loaded, entry point (manifested by assembly file) located and run. Any of us can create alternative host application running completely different type of assembly with completely different type of entry point (or even a set of different entry points) supporting completely different interface.
I discussed such architectures in my past solutions:
Create WPF Application that uses Reloadable Plugins...[
^],
AppDomain refuses to load an assembly[
^],
code generating using CodeDom[
^],
Create WPF Application that uses Reloadable Plugins...[
^],
Dynamically Load User Controls[
^].
From the other hand, .NET assembly represented by EXE file with which can work as traditional application can also be used as a regular class library. Any other assembly can reference it as a regular DLL. This fact is not very well known.
Finally, I promised to explain about
modules. Visual Studio supports only the simplified modular model: every assembly is represented by its only executable module, EXE or DLL file (or anything, just one executable file). The general model could be used if you make a custom build or just a bare C# compiler (I'm not sure about other compilers): every assembly can be composed of several different files called
modules. Don't mix modules with referenced assemblies: no one of the modules represent the whole assembly. A module cannot be referenced by other assembly, it can only be used to create a new assembly. The same module can participate in two (or more) different assemblies. The same code may work in different way in different assemblies. For example, different assemblies can have different
security permission. This would make some method placed in the module working properly when run in one assembly and fail in another one. One and only one of the modules in each assembly is called
main module. It carries
assembly manifest defining main assembly properties and identity. Again, with Visual Studio, each assembly is composed of just one module, so all modules are main.
—SA