elsa-core/src/common/Elsa.Mediator/Extensions/HandlerExtensions.cs
Sipke Schoorstra 490c8a2c9e
Addresses warnings and enforces null safety (#7050)
* Simplify test setup by removing `Input` wrapper and fix trimming warnings with `UnconditionalSuppressMessage` annotations.

* Add trimming warning suppression to `ArgumentJsonConverter` with `UnconditionalSuppressMessage`

- Annotated `Read` method to suppress `IL2055` warning caused by dynamic type resolution.
- Provided justification reflecting dynamic type registration in the well-known type registry.

* Add root namespace to project file and suppress EF Core usage warning

- Added `RootNamespace` property to `Elsa.Persistence.EFCore.Common.csproj` for consistency.
- Annotated `DbSchemaAwareMigrationAssembly` with `SuppressMessage` to suppress EF1001 usage warning and provide justification.

* Suppress obsolete API warnings in workflow runtime projects

- Added `#pragma warning disable CS0618` to suppress obsolete member warnings in `ObsoleteWorkflowRuntime.cs`, `LocalWorkflowRuntime.Obsolete.cs`, and `DistributedWorkflowRuntime.Obsolete.cs`.
- Updated `Directory.Build.props` to globally suppress `CS0618` for backward compatibility during migration.

* Annotate properties with non-nullable default initializers across modules to enforce null safety.

* Add `Priority` and `Deprecated` properties to `StorageDriverDescriptor` model

* Update src/modules/Elsa.Workflows.Runtime.Distributed/Services/DistributedWorkflowRuntime.Obsolete.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/modules/Elsa.Workflows.Runtime/Services/ObsoleteWorkflowRuntime.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/modules/Elsa.Workflows.Runtime/Services/LocalWorkflowRuntime.Obsolete.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Clean up XML comments and improve consistency across modules.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-12 15:53:23 +01:00

66 lines
3 KiB
C#

using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Elsa.Mediator.Contracts;
using Elsa.Mediator.Middleware.Command;
using Elsa.Mediator.Middleware.Notification;
using Elsa.Mediator.Models;
namespace Elsa.Mediator.Extensions;
/// <summary>
/// Contains helper methods for invoking notification handlers.
/// </summary>
public static class HandlerExtensions
{
/// <summary>
/// Gets the handle method for a notification handler of the given notification type.
/// </summary>
/// <param name="notificationType">The notification type.</param>
/// <returns>The handle method.</returns>
public static MethodInfo GetNotificationHandlerMethod(this Type notificationType)
{
var handlerType = typeof(INotificationHandler<>).MakeGenericType(notificationType);
return handlerType.GetMethod("HandleAsync")!;
}
/// <summary>
/// Gets the handle method for a command handler of the given command type.
/// </summary>
/// <param name="commandType">The command type.</param>
/// <returns>The handle method.</returns>
public static MethodInfo GetCommandHandlerMethod([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] this Type commandType)
{
var commandTypeInterfaces = commandType.GetInterfaces();
var commandTypeInterface = commandTypeInterfaces.FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ICommand<>));
var resultType = commandTypeInterface?.GetGenericArguments()[0] ?? typeof(Unit);
var handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, resultType);
return handlerType.GetMethod("HandleAsync")!;
}
/// <summary>
/// Invokes the given handler for the given notification.
/// </summary>
/// <param name="handler">The handler to invoke.</param>
/// <param name="handleMethod">The handle method.</param>
/// <param name="notificationContext">The notification context containing the notification and cancellation token.</param>
public static Task InvokeAsync(this INotificationHandler handler, MethodBase handleMethod, NotificationContext notificationContext)
{
var notification = notificationContext.Notification;
var cancellationToken = notificationContext.CancellationToken;
return (Task)handleMethod.Invoke(handler, [notification, cancellationToken])!;
}
/// <summary>
/// Invokes the given handler for the given command.
/// </summary>
/// <param name="handler">The handler to invoke.</param>
/// <param name="handleMethod">The handle method.</param>
/// <param name="commandContext">The command to handle.</param>
public static Task<TResult> InvokeAsync<TResult>(this ICommandHandler handler, MethodBase handleMethod, CommandContext commandContext)
{
var command = commandContext.Command;
var cancellationToken = commandContext.CancellationToken;
var task = (Task<TResult>)handleMethod.Invoke(handler, [command, cancellationToken])!;
return task;
}
}