About Windows Installer, the .NET Framework, and Visual Studio.
The Microsoft .NET Framework installs assemblies into two different locations, and this practice is recommended to developers wishing to deploy assemblies both for runtime and design-time use.
Runtime assemblies are those assemblies needed for an application to execute. It is recommended that you add runtime assemblies to the Global Assembly Cache (GAC). If you're deploying your assemblies in a Windows Installer package, you would add the file normally but then add records into the MsiAssembly and MsiAsemblyName tables. If you plan on doing in-place updates – though assembly versioning is recommended – be sure to add the FileVersion attribute to the MsiAssemblyName table.
Design-time assemblies are those assemblies you would compile and link against when building your own managed assemblies. In Visual Studio, these are assemblies you would see when you right-click on a project, for example, and click "Add References...". These assemblies are installed as any other normal files would be installed using Windows Installer, with the addition of a registry key under SOFTWARE\Microsoft\.NETFramework\AssemblyFolders – either under HKEY_LOCAL_MACHINE for all users, or HKEY_CURRENT_USER for the current user.
Since the .NET Framework provides the base class library, all the assemblies are co-installed into both locations. Components from other vendors may also do the same, while end user applications may install only into the GAC. Developers really should only install design-time assemblies they want users to reference in their own projects. These assemblies will certainly work with dependent assemblies installed only into the GAC.
An example WIX fragment follows. This was updated from the previous snippet to pass ICE30 validation and add the Assembly attribute that was mistakenly left out originally. Thanks to Aaron Stebner for pointing this out.
<Directory Id="ProductDirectory" Name="$(var.ProductName)">
<Directory Id="GAC" Name="GAC">
<Component Id="RT_MyControl" Guid="22887611-B13E-41EE-897C-D78830E68AEB" DiskId="1">
<!-- Runtime, assembly in GAC -->
<File Id="F_RT_MyControl" Name="MyCtrl.dll" LongName="MyControl.dll" Source="$(var.SrcPath)\MyControl.dll" KeyPath="yes" Assembly=".net"/>
<Component Id="DT_MyControl" Guid="FB935B7D-D2BD-4B83-A26C-A9376EBA0915" DiskId="1">
<!-- Design-time, private assembly -->
<File Id="F_DT_MyControl" Name="MyCtrl.dll" LongName="MyControl.dll" Source="$(var.SrcPath)\MyControl.dll" KeyPath="yes"/>
<Registry Id="R_DT_MyControl_AssemblyFolders" Root="HKLM" Key="SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\[ProductName]" Value="[$DT_MyControl]" Type="string"/>