| File: Instance\TaskFactories\RegisteredTaskFactory.cs | Web Access |
| Project: src\msbuild\src\Build\Microsoft.Build.csproj (Microsoft.Build) |
// 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.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Microsoft.Build.Framework; using Microsoft.Build.Shared; namespace Microsoft.Build.BackEnd { /// <summary> /// An <see cref="ITaskFactory"/> that constructs a task that a host registered through /// <see cref="TaskClassRegistry"/> (via <c>Microsoft.Build.Utilities.Task.RegisterTask</c>), with no /// assembly loading or by-name type resolution. /// </summary> /// <remarks> /// The engine instantiates a registered task by calling <see cref="CreateRegisteredTask"/> directly, /// which is reflection-free and avoids the <see cref="ITaskFactory.CreateTask"/> interface member (that /// member is <c>[RequiresUnreferencedCode]</c>, so calling it would reintroduce a trim warning). The /// <see cref="LoadedType"/> this factory exposes was built at registration from the registered, trim-rooted /// task type, so parameter discovery and binding stay trim-safe. /// </remarks> internal sealed class RegisteredTaskFactory : ITaskFactory { /// <summary> /// The registration that supplies the reflection-free constructor. /// </summary> private readonly TaskClassRegistration _registration; /// <summary> /// The reflected type metadata, built from the registered task type at registration time. /// </summary> private readonly LoadedType _loadedType; internal RegisteredTaskFactory(TaskClassRegistration registration, LoadedType loadedType) { _registration = registration; _loadedType = loadedType; } /// <inheritdoc /> public string FactoryName => "Registered Task Factory"; /// <inheritdoc /> [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] public Type TaskType => _loadedType.Type; /// <summary> /// Constructs a new instance of the registered task. Reflection-free: it invokes the registered /// factory. The engine calls this instead of <see cref="CreateTask"/> so no trim-unsafe interface /// member is reached on the registered-task path. /// </summary> /// <param name="taskEnvironment"> /// The environment the engine is running the task with, supplied to a registered task that declares a /// <see cref="TaskEnvironment"/> constructor so it can consume it during construction. /// </param> internal ITask CreateRegisteredTask(TaskEnvironment taskEnvironment) => _registration.CreateInstance(taskEnvironment); /// <inheritdoc /> public TaskPropertyInfo[] GetTaskParameters() => _loadedType.Properties; /// <inheritdoc /> [RequiresUnreferencedCode("Task factories create tasks by reflecting over a task type discovered or generated at runtime, which is incompatible with trimming.")] public bool Initialize(string taskName, IDictionary<string, TaskPropertyInfo> parameterGroup, string taskBody, IBuildEngine taskFactoryLoggingHost) => true; /// <inheritdoc /> [RequiresUnreferencedCode("Task factories create tasks by reflecting over a task type discovered or generated at runtime, which is incompatible with trimming.")] public ITask CreateTask(IBuildEngine taskFactoryLoggingHost) => _registration.CreateInstance(TaskEnvironment.Fallback); /// <inheritdoc /> public void CleanupTask(ITask task) { } } }