An assembly is the smallest .NET unit of deployment. Due to the self-describing nature of a manifest, deployment can be as simple as copying the assembly (and in the case of a multifile assembly, all the associated files) into the application directory.
This is a vast improvement over traditional COM development, in which components, their supporting DLLs, and their configuration information are spread out over multiple directories and the Windows registry.
In many cases, we want to share assemblies between applications. The foremost way to do this is to sign the assemblies, then place them in the machine-wide global assembly cache (GAC), which all applications have access to. The assembly resolver always consults the GAC before looking elsewhere for the assembly, so this is the fastest option.
Next, assemblies may be deployed at http: and file: URI endpoints. To do this, deploy them in the correct location and use the application and machine configuration files to tell the assembly resolver where to look using the <codeBase> element. (See the .NET Framework SDK documentation for the specific format of the configuration files.)
Lastly, if we do not wish to share assemblies between applications, we can place them in or beneath the application directory. When deployed in this way, the assembly resolver finds them by probing for a file with the name matching the simple name of the assembly and either a .dll or .exe extension. The directories that the resolver probes in follow a well-defined set of rules (see the .NET Framework SDK documentation for more details) and can be controlled by the configuration files with the <probing> element.