Assembly

De Banane Atomic
Aller à la navigationAller à la recherche

Comment le runtime cherche les assemblies

  1. Assemblies already loaded
  2. GAC
  3. codeBase
  4. Application's root directory
    1. No culture information
      1. [assembly name].dll
      2. [assembly name] / [assembly name].dll
    2. Culture information is specified for the referenced assembly
      1. [culture] / [assembly name].dll
      2. [culture] / [assembly name] / [assembly name].dll
    3. privatePath (sous dossiers)
      1. No culture information
        1. [privatePath] / [assembly name].dll
        2. [privatePath] / [assembly name] / [assembly name].dll
      2. Culture information is specified for the referenced assembly
        1. [privatePath] / [culture] / [assembly name].dll
        2. [privatePath] / [culture] / [assembly name] / [assembly name].dll

Obtenir la version

Csharp.svg
GetType().Assembly.GetName().Version.ToString();
Assembly.GetEntryAssembly().GetName().Version.ToString();

var simplifiedVersion = Regex.Replace(version, "(\\.0)+$", string.Empty);
Powershell.svg
[Reflection.AssemblyName]::GetAssemblyName('MonAssembly.dll').Version

Assembly vs File vs Product version

  • If Assembly version is not explictly specified, it takes the value of 0.0.0.0.
  • If File version is not explicitly specified, it takes the value of Assembly version.
  • If Product version is not explicitly specified, it takes the value of File version.

Assembly

Csharp.svg
// L'exécutable
Assembly entryAssembly = Assembly.GetEntryAssembly();
// L'assemblage en cours d'exécution
Assembly executingAssembly = Assembly.GetExecutingAssembly();
// L'assemblage ayant appelé la méthode en cours d'exécution
Assembly callingAssembly = Assembly.GetCallingAssembly();

// Charger une assembly depuis son nom
Assembly assembly = Assembly.Load("Namespace.Class, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
Assembly assembly = Assembly.LoadWithPartialName("Namespace.Class");

// Charger une assembly depuis un de ses types
Assembly assembly = Assembly.GetAssembly(typeof(Console));

// chemin vers le fichier *.exe
string path = Assembly.GetEntryAssembly().Location;
// chemin vers le dossier contenant le fichier *.exe
string folder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

// Version
Version assemblyVersion = Assembly.GetEntryAssembly().GetName().Version;
string stringAssemblyVersion = assemblyVersion.ToString(); // "1.0.0.0"

string fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
string productVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;

LoadFile vs LoadFrom

  • LoadFrom utilise Fusion et peut charger une autre assembly situé dans un autre chemin mais avec la même identité si celle-ci est déjà chargée dans le LoadFrom context.
  • LoadFile n'utilise pas Fusion, c'est exactement l'assembly demandé qui est chargée. Les dépendances ne sont pas automatiquement trouvées dans son dossier. Si elles ne sont pas disponibles dans le Load context, il faut utiliser l'event AssemblyResolve pour les lier.
Method Advantages Disadvantages
Load Gets the benefits of versioning and policy.

Dependencies available in the Load context are automatically found.

Dependencies in other contexts are not available unless you subscribe to the AppDomain.AssemblyResolve event.
LoadFrom Assemblies can be loaded from multiple paths, not just from beneath the ApplicationBase.

Dependencies already loaded in this context will automatically be found.
Dependencies in the same dir as the requesting LoadFrom context assembly will automatically be found.

If a Load context assembly tries to load this assembly by display name, it will fail to be found, by default (e.g., when mscorlib.dll deserializes this assembly).

Worse, an assembly with the same identity, but at a different path, could be found on the probing path, causing an InvalidCastException, MissingMethodException, or unexpected method behavior, later on.
If an assembly by the same identity is already loaded, you’ll get that one back, even if you’ve specified a path to a different one.
It does a FileIOPermission.Read + PathDiscovery demand, or a WebPermission demand, on the path/URL specified.

LoadFile Avoids probing costs for loading this assembly.

You can load multiple assemblies with the same identity into the same appdomain.

Nothing can bind to this assembly unless you’ve subscribed to the AssemblyResolve event.

Dependencies can only be loaded from the Load context or using the AssemblyResolve event.
Passing this assembly to another AppDomain may become tricky (e.g., when this is a Reflection Emit assembly that hasn’t been saved).

Assembly.Load vs LoadFile vs LoadFrom

OnAssemblyResolve

Cs.svg
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;

Fuslogvw.exe (Assembly Binding Log Viewer)

Attributs de l'assemblage

Cs.svg
// Description
object[] attributes = _assembly.GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
if (attributes.Length != 0)
{
    string description = ((AssemblyDescriptionAttribute)attributes[0]).Description;
}

// Product
object[] attributes = _assembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
if (attributes.Length != 0)
{
    string product = ((AssemblyProductAttribute)attributes[0]).Product;
}

// Copyright
object[] attributes = _assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
if (attributes.Length != 0)
{
    string copyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}

// Company
object[] attributes = _assembly.GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length != 0)
{
    string company= ((AssemblyCompanyAttribute)attributes[0]).Company;
}

// Guid
object[] attributes = _assembly.GetCustomAttributes(typeof(GuidAttribute), false);
if (attributes.Length != 0)
{
    string guid = ((GuidAttribute)attributes[0]).Value;
}

// ClientCompany
object[] attributes = _assembly.GetCustomAttributes(typeof(ClientCompanyAttribute), false);
if (attributes.Length != 0)
{
    string clientCompany= ((ClientCompanyAttribute)attributes[0]).ClientCompany;
}