Assembly Names

An assembly's name is stored in metadata and has a significant impact on the assembly's scope and use by an application. A strong-named assembly has a fully qualified name that includes the assembly's name, culture, public key, and version number. The runtime uses this information to locate the assembly and differentiate it from other assemblies with the same name. For example, a strong-named assembly called myTypes could have the following fully qualified name:

"myTypes, Version=1.0.1234.0, Culture="en-US", PublicKeyToken=b77a5c561934e089c

In this example, the fully qualified name indicates that the myTypes assembly has a strong name with a public key token, has the culture value for US English, and has a version number of 1.0.1234.0.

Code that requests types in an assembly must use a fully qualified assembly name. This is called fully qualified binding. Partial binding, which specifies only an assembly name, is not permitted when referencing assemblies in the .NET Framework.

All assembly references to assemblies that make up the .NET Framework also must contain a fully qualified name of the assembly. For example, to reference the System.Data .NET Framework assembly for version 1.0 would include:

System.data, version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Note that the version corresponds to the version number of all .NET Framework assemblies that shipped with .NET Framework version 1.0. For .NET Framework assemblies, the culture value is always neutral, and the public key is the same as shown in the above example.

For example, to add an assembly reference in a configuration file to set up a trace listener, you would include the fully qualified name of the system .NET Framework assembly:

<add name="myListener" type="System.Diagnostics.TextWriterTraceListener, system version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="c:\myListener.log" />

Note   The runtime treats assembly names as case-insensitive when binding to an assembly, but preserves whatever case is used in an assembly name. Several tools in the .NET Framework SDK handle assembly names as case-sensitive. For best results, manage assembly names as though they were case-sensitive.

Determining an Assembly's Fully Qualified Name

There are several ways to discover the fully qualified name of an assembly in the global assembly cache:

To view the fully qualified names of assemblies in the global assembly cache using the .NET Framework Configuration tool

  1. Click the Start button, point to Administrative Tools, and then click Microsoft .NET Framework Configuration.
  2. Click Manage the Assembly Cache, and then click View List of Assemblies in the Assembly Cache.

For information about using the Global Assembly Cache tool to view the fully qualified names of assemblies, see Viewing the Contents of the Global Assembly Cache.

For assemblies that are not in the global assembly cache, you can use code to output the information to the console or to a variable, or you can use the MSIL Disassembler (Ildasm.exe) to examine the assembly's metadata, which contains the fully qualified name.

The following code example shows how to display the fully qualified name of an assembly containing a specified class to the console.

using System;
using System.Reflection;
class asmname
{
    public static void Main()
    {
        Type t = typeof(System.Data.DataSet);
        string s = t.Assembly.FullName.ToString();
        Console.WriteLine("The fully qualified assembly name containing the specified class is {0}.", s);
    }
}
[Visual Basic]Imports System
Imports System.Reflection
Imports Microsoft.VisualBasic
' For a class not contained in mscorlib.dll, compile this code with 
' the /r:<dllname> option; for example,compile the code below using:
'    vbc asmname.vb /r:System.Data.dll /r:System.dll /r:System.Xml.dll
' If the class is contained in mscorlib.dll, the /r:<dllname> compiler option is unnecessary.

Class asmname
    Public Shared Sub Main()
        Dim t As Type = GetType(System.Data.DataSet)
        Console.WriteLine("The fully qualified assembly name containing the specified class is {0}.", t.Assembly.FullName.ToString())
    End Sub 'Main
End Class 'asmname

For more information about setting assembly attributes such as version, culture, and assembly name, see Setting Assembly Attributes. For more information about giving an assembly a strong name, see Creating and Using Strong-Named Assemblies.

Naming Application Components

The runtime does not consider the file name when determining an assembly's identity. The assembly identity, which consists of the assembly name, version, culture, and strong name, must be clear to the runtime.

For example, if you have an assembly called myAssembly.exe that references an assembly called myAssembly.dll, binding occurs correctly if you execute myAssembly.exe. However, if another application executes myAssembly.exe using the method AppDomain.ExecuteAssembly, the runtime determines that "myAssembly" is already loaded when myAssembly.exe requests binding to "myAssembly." In this case, myAssembly.dll is never loaded. Because myAssembly.exe does not contain the requested type , a TypeLoadException occurs.

To avoid this problem, make sure the assemblies that make up your application do not have the same assembly name or place assemblies with the same name in different directories.

Note   If you put a strong-named assembly in the global assembly cache, the assembly's file name must match the assembly name (not including the file name extension, such as .exe or .dll). For example, if the file name of an assembly is myAssembly.dll, the assembly name must be myAssembly. Private assemblies deployed only in the root application directory can have an assembly name that is different from the file name.

See Also

Creating Assemblies | Strong-Named Assemblies | Global Assembly Cache | How the Runtime Locates Assemblies | Programming with Assemblies