-
Notifications
You must be signed in to change notification settings - Fork 871
Expand file tree
/
Copy pathCommandLineArgsCallbackAnnotation.cs
More file actions
128 lines (108 loc) · 5.08 KB
/
CommandLineArgsCallbackAnnotation.cs
File metadata and controls
128 lines (108 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 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 Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Aspire.Hosting.ApplicationModel;
using IArgCallbackAnnotation = ICallbackResourceAnnotation<CommandLineArgsCallbackContext, IList<object>>;
/// <summary>
/// Represents an annotation that provides a callback to be executed with a list of command-line arguments when an executable resource is started.
/// </summary>
public class CommandLineArgsCallbackAnnotation : IResourceAnnotation, IArgCallbackAnnotation
{
private Task<IList<object>>? _callbackTask;
private readonly object _lock = new();
/// <summary>
/// Initializes a new instance of the <see cref="CommandLineArgsCallbackAnnotation"/> class with the specified callback action.
/// </summary>
/// <param name="callback"> The callback action to be executed.</param>
public CommandLineArgsCallbackAnnotation(Func<CommandLineArgsCallbackContext, Task> callback)
{
ArgumentNullException.ThrowIfNull(callback);
Callback = callback;
}
/// <summary>
/// Initializes a new instance of the <see cref="CommandLineArgsCallbackAnnotation"/> class with the specified callback action.
/// </summary>
/// <param name="callback"> The callback action to be executed.</param>
public CommandLineArgsCallbackAnnotation(Action<IList<object>> callback)
{
ArgumentNullException.ThrowIfNull(callback);
Callback = (c) =>
{
callback(c.Args);
return Task.CompletedTask;
};
}
/// <summary>
/// Gets the callback action to be executed when the executable arguments are parsed.
/// </summary>
public Func<CommandLineArgsCallbackContext, Task> Callback { get; }
internal IArgCallbackAnnotation AsCallbackAnnotation() => this;
Task<IList<object>> IArgCallbackAnnotation.EvaluateOnceAsync(CommandLineArgsCallbackContext context)
{
lock(_lock)
{
if (_callbackTask is null)
{
_callbackTask = ExecuteCallbackAsync(context);
}
return _callbackTask;
}
}
void IArgCallbackAnnotation.ForgetCachedResult()
{
lock(_lock)
{
_callbackTask = null;
}
}
private async Task<IList<object>> ExecuteCallbackAsync(CommandLineArgsCallbackContext context)
{
await Callback(context).ConfigureAwait(false);
var result = context.Args.ToImmutableList();
return result;
}
}
/// <summary>
/// Represents a callback context for the list of command-line arguments associated with an executable resource.
/// </summary>
/// <param name="args"> The list of command-line arguments.</param>
/// <param name="cancellationToken"> The cancellation token associated with this execution.</param>
[AspireExport(ExposeProperties = true)]
public sealed class CommandLineArgsCallbackContext(IList<object> args, CancellationToken cancellationToken = default)
{
private readonly IResource? _resource;
/// <summary>
/// Represents a callback context for the list of command-line arguments associated with an executable resource.
/// </summary>
/// <param name="args"> The list of command-line arguments.</param>
/// <param name="resource"> The resource associated with this callback context.</param>
/// <param name="cancellationToken"> The cancellation token associated with this execution.</param>
public CommandLineArgsCallbackContext(IList<object> args, IResource resource, CancellationToken cancellationToken = default)
: this(args, cancellationToken) => _resource = resource ?? throw new ArgumentNullException(nameof(resource));
/// <summary>
/// Gets the list of command-line arguments.
/// </summary>
public IList<object> Args { get; } = args ?? throw new ArgumentNullException(nameof(args));
/// <summary>
/// Gets the cancellation token associated with the callback context.
/// </summary>
public CancellationToken CancellationToken { get; } = cancellationToken;
/// <summary>
/// Gets or sets the execution context for the distributed application.
/// </summary>
public DistributedApplicationExecutionContext ExecutionContext { get; init; } = new(DistributedApplicationOperation.Run);
/// <summary>
/// Gets or sets the logger for the distributed application.
/// </summary>
public ILogger Logger { get; init; } = NullLogger.Instance;
/// <summary>
/// The resource associated with this callback context.
/// </summary>
/// <remarks>
/// This will be set to the resource in all cases where Aspire invokes the callback.
/// </remarks>
/// <exception cref="InvalidOperationException">Thrown when the EnvironmentCallbackContext was created without a specified resource.</exception>
public IResource Resource => _resource ?? throw new InvalidOperationException($"{nameof(Resource)} is not set. This callback context is not associated with a resource.");
}