| File: Utilities\AssemblyLoadInfo.cs | Web Access |
| Project: src\msbuild\src\Framework\Microsoft.Build.Framework.csproj (Microsoft.Build.Framework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using System.IO; using Microsoft.Build.BackEnd; #nullable disable namespace Microsoft.Build.Shared { /// <summary> /// This class packages information about how to load a given assembly -- an assembly can be loaded by either its assembly /// name (strong or weak), or its filename/path. /// </summary> /// <remarks> /// Uses factory to instantiate correct private class to save space: only one field is ever used of the two. /// </remarks> internal abstract class AssemblyLoadInfo : ITranslatable, IEquatable<AssemblyLoadInfo> { /// <summary> /// This constructor initializes the assembly information. /// </summary> internal static AssemblyLoadInfo Create(string assemblyName, string assemblyFile) { Assumed.True( (!string.IsNullOrEmpty(assemblyName)) || (!string.IsNullOrEmpty(assemblyFile)), "We must have either the assembly name or the assembly file/path."); Assumed.True( (assemblyName == null) || (assemblyFile == null), "We must not have both the assembly name and the assembly file/path."); if (assemblyName != null) { return new AssemblyLoadInfoWithName(assemblyName); } else { return new AssemblyLoadInfoWithFile(assemblyFile); } } /// <summary> /// Gets the assembly's identity denoted by its strong/weak name. /// </summary> public abstract string AssemblyName { get; } /// <summary> /// Gets the path to the assembly file. /// </summary> public abstract string AssemblyFile { get; } /// <summary> /// Get the assembly location /// </summary> internal abstract string AssemblyLocation { get; } /// <summary> /// Gets whether this assembly is an inline task assembly that should be loaded from bytes to avoid file locking. /// </summary> internal abstract bool IsInlineTask { get; } /// <summary> /// Computes a hashcode for this assembly info, so this object can be used as a key into /// a hash table. /// </summary> public override int GetHashCode() { return AssemblyLocation.GetHashCode(); } public bool Equals(AssemblyLoadInfo other) { return Equals((object)other); } /// <summary> /// Determines if two AssemblyLoadInfos are effectively the same. /// </summary> public override bool Equals(Object obj) { if (obj == null) { return false; } AssemblyLoadInfo otherAssemblyInfo = obj as AssemblyLoadInfo; if (otherAssemblyInfo == null) { return false; } return (this.AssemblyName == otherAssemblyInfo.AssemblyName) && (this.AssemblyFile == otherAssemblyInfo.AssemblyFile); } public void Translate(ITranslator translator) { Assumed.Equal(translator.Mode, TranslationDirection.WriteToStream, "write only"); string assemblyName = AssemblyName; string assemblyFile = AssemblyFile; translator.Translate(ref assemblyName); translator.Translate(ref assemblyFile); } public static AssemblyLoadInfo FactoryForTranslation(ITranslator translator) { string assemblyName = null; string assemblyFile = null; translator.Translate(ref assemblyName); translator.Translate(ref assemblyFile); return Create(assemblyName, assemblyFile); } /// <summary> /// Assembly represented by name /// </summary> [DebuggerDisplay("{AssemblyName}")] private sealed class AssemblyLoadInfoWithName : AssemblyLoadInfo { /// <summary> /// Assembly name /// </summary> private string _assemblyName; /// <summary> /// Constructor /// </summary> internal AssemblyLoadInfoWithName(string assemblyName) { _assemblyName = assemblyName; } /// <summary> /// Gets the assembly's identity denoted by its strong/weak name. /// </summary> public override string AssemblyName { get { return _assemblyName; } } /// <summary> /// Gets the path to the assembly file. /// </summary> public override string AssemblyFile { get { return null; } } /// <summary> /// Get the assembly location /// </summary> internal override string AssemblyLocation { get { return _assemblyName; } } /// <summary> /// Gets whether this assembly is an inline task assembly. /// Assembly names are never inline tasks. /// </summary> internal override bool IsInlineTask { get { return false; } } } /// <summary> /// Assembly info that uses a file path /// </summary> [DebuggerDisplay("{AssemblyFile}")] private sealed class AssemblyLoadInfoWithFile : AssemblyLoadInfo { /// <summary> /// Path to assembly /// </summary> private string _assemblyFile; /// <summary> /// Constructor /// </summary> internal AssemblyLoadInfoWithFile(string assemblyFile) { Assumed.True(Path.IsPathRooted(assemblyFile), "Assembly file path should be rooted"); _assemblyFile = assemblyFile; } /// <summary> /// Gets the assembly's identity denoted by its strong/weak name. /// </summary> public override string AssemblyName { get { return null; } } /// <summary> /// Gets the path to the assembly file. /// </summary> public override string AssemblyFile { get { return _assemblyFile; } } /// <summary> /// Get the assembly location /// </summary> internal override string AssemblyLocation { get { return _assemblyFile; } } /// <summary> /// Gets whether this assembly is an inline task assembly. /// Detects inline tasks by checking if the file path ends with the inline task suffix. /// </summary> internal override bool IsInlineTask { get { return _assemblyFile?.EndsWith(TaskFactoryUtilities.InlineTaskSuffix, StringComparison.OrdinalIgnoreCase) == true; } } } } }