| File: BackEnd\HostServicesData.cs | Web Access |
| Project: 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.Collections.Immutable; using System.Runtime.InteropServices; namespace Microsoft.Build.BackEnd; /// <summary> /// Contains the remote host object registrations transferred to a task host. /// </summary> /// <remarks> /// In-process host objects and project node affinities are not part of this payload. /// </remarks> internal sealed class HostServicesData : ITranslatable { public static HostServicesData Empty { get; } = new(registrations: []); private ImmutableArray<Registration> _registrations; /// <summary> /// Initializes a new instance of the <see cref="HostServicesData"/> class. /// </summary> /// <param name="registrations">The initialized array of remote host object registrations in wire order.</param> public HostServicesData(ImmutableArray<Registration> registrations) { Assumed.True(!registrations.IsDefault, "The remote host object registrations must be initialized."); _registrations = registrations; } /// <summary> /// Gets the remote host object registrations in wire order. /// </summary> public ImmutableArray<Registration> Registrations => _registrations; /// <summary> /// Creates host services initialized with the remote registrations. /// </summary> /// <typeparam name="T">The host-services type implementing <see cref="IRemoteHostServicesInitializer"/>.</typeparam> /// <returns> /// A new host-services instance containing the remote registrations. /// </returns> public T CreateHostServices<T>() where T : class, IRemoteHostServicesInitializer, new() { T hostServices = new(); hostServices.Initialize(this); return hostServices; } /// <summary> /// Translates the remote registrations using the existing host-services wire format. /// </summary> /// <param name="translator">The translator to use.</param> public void Translate(ITranslator translator) { if (translator.Mode == TranslationDirection.ReadFromStream) { int count = translator.Reader.ReadInt32(); if (count == 0) { _registrations = []; } else { Registration[] registrations = new Registration[count]; for (int i = 0; i < count; i++) { registrations[i] = new Registration( translator.Reader.ReadString(), translator.Reader.ReadString(), translator.Reader.ReadString(), translator.Reader.ReadString()); } _registrations = ImmutableCollectionsMarshal.AsImmutableArray(registrations); } } else { translator.Writer.Write(_registrations.Length); foreach (Registration registration in _registrations) { // These strings have no presence markers in the legacy HostServices payload. translator.Writer.Write(registration.ProjectFile); translator.Writer.Write(registration.TargetName); translator.Writer.Write(registration.TaskName); translator.Writer.Write(registration.MonikerName); } } } /// <summary> /// Deserializes the remote host object registrations. /// </summary> /// <param name="translator">The translator to use.</param> /// <returns> /// The deserialized host-services data. /// </returns> public static HostServicesData FactoryForDeserialization(ITranslator translator) { HostServicesData data = new([]); data.Translate(translator); return data; } /// <summary> /// Identifies a remote host object by its project, target, task, and COM moniker. /// </summary> /// <param name="ProjectFile">The project file associated with the host object.</param> /// <param name="TargetName">The target associated with the host object.</param> /// <param name="TaskName">The task associated with the host object.</param> /// <param name="MonikerName">The host object's registration name in the Running Object Table.</param> public readonly record struct Registration(string ProjectFile, string TargetName, string TaskName, string MonikerName); }