-
Notifications
You must be signed in to change notification settings - Fork 58
Expand file tree
/
Copy pathDurableTaskRegistry.cs
More file actions
180 lines (161 loc) · 8.21 KB
/
Copy pathDurableTaskRegistry.cs
File metadata and controls
180 lines (161 loc) · 8.21 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Linq;
using Microsoft.DurableTask.Entities;
namespace Microsoft.DurableTask;
/// <summary>
/// Container for registered <see cref="ITaskOrchestrator" />, <see cref="ITaskActivity" />,
/// and <see cref="ITaskEntity"/> implementations.
/// </summary>
public sealed partial class DurableTaskRegistry
{
static readonly Task<object?> CompletedNullTask = Task.FromResult<object?>(null);
/// <summary>
/// Gets the currently registered activities, keyed by <see cref="TaskName"/> and <see cref="TaskVersion"/>.
/// </summary>
internal IDictionary<TaskVersionKey, Func<IServiceProvider, ITaskActivity>> ActivitiesByVersion { get; }
= new Dictionary<TaskVersionKey, Func<IServiceProvider, ITaskActivity>>();
/// <summary>
/// Gets the currently registered orchestrators, keyed by <see cref="TaskName"/> and <see cref="TaskVersion"/>.
/// </summary>
internal IDictionary<TaskVersionKey, Func<IServiceProvider, ITaskOrchestrator>> OrchestratorsByVersion { get; }
= new Dictionary<TaskVersionKey, Func<IServiceProvider, ITaskOrchestrator>>();
/// <summary>
/// Gets the currently registered entities.
/// </summary>
internal IDictionary<TaskName, Func<IServiceProvider, ITaskEntity>> Entities { get; }
= new Dictionary<TaskName, Func<IServiceProvider, ITaskEntity>>();
/// <summary>
/// Gets the currently registered orchestrators as a name-keyed enumeration. One entry per
/// registration; multi-version registrations appear as multiple entries sharing the same
/// <see cref="TaskName"/>.
/// </summary>
/// <remarks>
/// This shape preserves binary compatibility with the currently shipped
/// <c>Microsoft.Azure.Functions.Worker.Extensions.DurableTask</c> 1.4.0, which reflects on this
/// property and casts it to
/// <see cref="IEnumerable{T}"/> of
/// <see cref="KeyValuePair{TKey, TValue}"/> of <see cref="TaskName"/> and
/// <c>Func<IServiceProvider, ITaskOrchestrator></c>. Internal SDK code should use
/// <see cref="OrchestratorsByVersion"/>; external code should use <see cref="GetOrchestrators"/>.
/// </remarks>
internal IEnumerable<KeyValuePair<TaskName, Func<IServiceProvider, ITaskOrchestrator>>> Orchestrators
=> this.OrchestratorsByVersion.Select(kvp =>
new KeyValuePair<TaskName, Func<IServiceProvider, ITaskOrchestrator>>(new TaskName(kvp.Key.Name), kvp.Value));
/// <summary>
/// Gets the currently registered activities as a name-keyed enumeration. One entry per
/// registration; multi-version registrations appear as multiple entries sharing the same
/// <see cref="TaskName"/>.
/// </summary>
/// <remarks>
/// This shape preserves binary compatibility with the currently shipped
/// <c>Microsoft.Azure.Functions.Worker.Extensions.DurableTask</c> 1.4.0, which reflects on this
/// property and casts it to
/// <see cref="IEnumerable{T}"/> of
/// <see cref="KeyValuePair{TKey, TValue}"/> of <see cref="TaskName"/> and
/// <c>Func<IServiceProvider, ITaskActivity></c>. Internal SDK code should use
/// <see cref="ActivitiesByVersion"/>; external code should use <see cref="GetActivities"/>.
/// </remarks>
internal IEnumerable<KeyValuePair<TaskName, Func<IServiceProvider, ITaskActivity>>> Activities
=> this.ActivitiesByVersion.Select(kvp =>
new KeyValuePair<TaskName, Func<IServiceProvider, ITaskActivity>>(new TaskName(kvp.Key.Name), kvp.Value));
/// <summary>
/// Enumerates the registered orchestrators. One entry per registration; multi-version
/// registrations appear as multiple entries sharing the same <see cref="TaskName"/>.
/// </summary>
/// <returns>
/// An enumeration of <see cref="KeyValuePair{TKey, TValue}"/> pairs where the key is the
/// orchestrator <see cref="TaskName"/> and the value is the factory delegate.
/// </returns>
public IEnumerable<KeyValuePair<TaskName, Func<IServiceProvider, ITaskOrchestrator>>> GetOrchestrators()
=> this.Orchestrators;
/// <summary>
/// Enumerates the registered activities. One entry per registration; multi-version
/// registrations appear as multiple entries sharing the same <see cref="TaskName"/>.
/// </summary>
/// <returns>
/// An enumeration of <see cref="KeyValuePair{TKey, TValue}"/> pairs where the key is the
/// activity <see cref="TaskName"/> and the value is the factory delegate.
/// </returns>
public IEnumerable<KeyValuePair<TaskName, Func<IServiceProvider, ITaskActivity>>> GetActivities()
=> this.Activities;
/// <summary>
/// Enumerates the registered entities.
/// </summary>
/// <returns>
/// An enumeration of <see cref="KeyValuePair{TKey, TValue}"/> pairs where the key is the
/// entity <see cref="TaskName"/> and the value is the factory delegate.
/// </returns>
public IEnumerable<KeyValuePair<TaskName, Func<IServiceProvider, ITaskEntity>>> GetEntities()
=> this.Entities.Select(kvp => kvp);
/// <summary>
/// Registers an activity factory.
/// </summary>
/// <param name="name">The name of the activity.</param>
/// <param name="factory">The activity factory.</param>
/// <returns>This registry instance, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if any of the following are true:
/// <list type="bullet">
/// <item>If <paramref name="name"/> is <c>default</c>.</item>
/// <item>If <paramref name="name" /> is already registered.</item>
/// <item>If <paramref name="factory"/> is <c>null</c>.</item>
/// </list>
/// </exception>
public DurableTaskRegistry AddActivity(TaskName name, Func<IServiceProvider, ITaskActivity> factory)
=> this.AddActivity(name, default, factory);
/// <summary>
/// Registers an entity factory.
/// </summary>
/// <param name="name">The name of the entity.</param>
/// <param name="factory">The entity factory.</param>
/// <returns>This registry instance, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if any of the following are true:
/// <list type="bullet">
/// <item>If <paramref name="name"/> is <c>default</c>.</item>
/// <item>If <paramref name="name" /> is already registered.</item>
/// <item>If <paramref name="factory"/> is <c>null</c>.</item>
/// </list>
/// </exception>
public DurableTaskRegistry AddEntity(TaskName name, Func<IServiceProvider, ITaskEntity> factory)
{
Check.NotDefault(name);
Check.NotNull(factory);
if (this.Entities.ContainsKey(name))
{
throw new ArgumentException($"An {nameof(ITaskEntity)} named '{name}' is already added.", nameof(name));
}
this.Entities.Add(name, factory);
return this;
}
DurableTaskRegistry AddActivity(TaskName name, TaskVersion version, Func<IServiceProvider, ITaskActivity> factory)
{
Check.NotDefault(name);
Check.NotNull(factory);
TaskVersionKey key = new(name, version);
if (this.ActivitiesByVersion.ContainsKey(key))
{
string message = string.IsNullOrEmpty(version.Version)
? $"An {nameof(ITaskActivity)} named '{name}' is already added."
: $"An {nameof(ITaskActivity)} named '{name}' with version '{version.Version}' is already added.";
throw new ArgumentException(message, nameof(name));
}
this.ActivitiesByVersion.Add(key, factory);
return this;
}
/// <summary>
/// Registers an activity factory under every supplied version. This is the shared fan-out used by the
/// type- and singleton-based registration overloads so that a class declaring multiple versions via
/// <see cref="DurableTaskAttribute.Version"/> is registered once per declared version.
/// </summary>
DurableTaskRegistry AddActivityAllVersions(
TaskName name, IReadOnlyList<TaskVersion> versions, Func<IServiceProvider, ITaskActivity> factory)
{
foreach (TaskVersion version in versions)
{
this.AddActivity(name, version, factory);
}
return this;
}
}