File: System\Reflection\TypeLoading\Assemblies\Ecma\EcmaAssembly.GetName.cs
Web Access
Project: src\src\libraries\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj (System.Reflection.MetadataLoadContext)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Reflection.Metadata;
 
namespace System.Reflection.TypeLoading.Ecma
{
    /// <summary>
    /// Base class for all Assembly objects created by a MetadataLoadContext and get its metadata from a PEReader.
    /// </summary>
    internal sealed partial class EcmaAssembly
    {
        protected sealed override AssemblyNameData ComputeNameData()
        {
            MetadataReader reader = Reader;
            AssemblyDefinition ad = AssemblyDefinition;
            AssemblyNameData data = new AssemblyNameData
            {
                Name = ad.Name.GetString(reader),
                Version = ad.Version,
                CultureName = ad.Culture.GetStringOrNull(reader) ?? string.Empty
            };
            byte[] pk = ad.PublicKey.GetBlobBytes(reader);
            data.PublicKey = pk;
            if (pk.Length != 0)
            {
                // AssemblyName will automatically compute the PKT on demand but given that we're doing all this work and caching it, we might
                // as well do this now.
                data.PublicKeyToken = pk.ComputePublicKeyToken();
            }
 
            AssemblyNameFlags anFlagsAndContentType = ad.Flags.ToAssemblyNameFlags() | AssemblyNameFlags.PublicKey;
            data.Flags = anFlagsAndContentType.ExtractAssemblyNameFlags();
 
            // We've finished setting the AssemblyName properties that actually pertain to binding and the Ecma-355
            // concept of an assembly name.
            //
            // The rest of the properties are properties historically set by the runtime Reflection and thumbtacked
            // onto the AssemblyName object in the CLR tradition of treating AssemblyName as a dumping ground for all
            // kinds of info. Nevertheless, some of this info is potentially useful and not exposed elsewhere on Assembly
            // so we'll be nice and set it.
            data.HashAlgorithm = ad.HashAlgorithm.ToConfigurationAssemblyHashAlgorithm();
            data.ContentType = anFlagsAndContentType.ExtractAssemblyContentType();
 
            ManifestModule.GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine);
            switch (machine)
            {
                case ImageFileMachine.AMD64:
                    data.ProcessorArchitecture = ProcessorArchitecture.Amd64;
                    break;
 
                case ImageFileMachine.ARM:
                    data.ProcessorArchitecture = ProcessorArchitecture.Arm;
                    break;
 
                case ImageFileMachine.IA64:
                    data.ProcessorArchitecture = ProcessorArchitecture.IA64;
                    break;
 
                case ImageFileMachine.I386:
                    if ((peKind & PortableExecutableKinds.Required32Bit) != 0)
                        data.ProcessorArchitecture = ProcessorArchitecture.X86;
                    else
                        data.ProcessorArchitecture = ProcessorArchitecture.MSIL;
                    break;
 
                default:
                    // No real precedent for what to do here - CLR will never get as far as giving you an Assembly object
                    // if the PE file specifies an unsupported machine. Since this Reflection implementation is a metadata inspection
                    // layer, and the library will never make any decisions based on this value, throwing isn't really the best response here.
                    data.ProcessorArchitecture = ProcessorArchitecture.None;
                    break;
            }
            return data;
        }
    }
}