mercredi 16 juin 2021

Locate CommandHandler from Command

I have 2 command interfaces:

public interface ICommand {}
public interface ICommand<TResult> {}

I have 2 command handler interfaces:

public interface ICommandHandler<in TCommand> where TCommand : ICommand
{
    Task HandleAsync(TCommand);
}
public interface ICommandHandler<in TCommand, TResult> where TCommand : ICommand<TResult>
{
    Task<TResult> HandleAsync(TCommand);
}

I have 2 command implementations

public class CreateWidgetCommand : ICommand<Guid>
{
    public string Name { get; set; }
}

public class DeleteWidgetCommand : ICommand
{
    public Guid Id { get; set; }
}

I have 2 command handler implementations

public class CreateWidgetCommandHandler : ICommandHandler<CreateWidgetCommand, Guid>
{
    public Task<Guid> HandleAsync(CreateWidgetCommand command)
    {
        // Save the widget
        // Return the Guid Id
    }
}
public class DeleteWidgetCommandHandler : ICommandHandler<DeleteWidgerCommand>
{
    public Task HandleAsync(DeleteWidgetCommand command)
    {
        // Delete the widget
    }
}

I now have root module object

public class WidgetModule
{
    public async Task<TResult> ExecuteCommandAsync<TResult>(ICommand<TResult> command)
    {
        // NEED TO FIND THE HANDLER THAT IMPLEMENTS ...
        // ... ICommandHandler<command type, TResult>
        // AND THEN CONSTRUCT IT AND EXECUTE

        // MY BEST EFFORT SO FAR:

        // Create the interface that must be implemented by the CommandHandler
        Type commandType = command.GetType();
        Type handlerType = typeof(ICommandHandler<,>);
        Type[] handlerArgs = { commandType, typeof(TResult) };
        Type handlerInterfaceConstructed = handlerType.MakeGenericType(handlerArgs);

        // Find the concrete type that implements this interface
        Type concreteHandlerType = System.Reflection.Assembly
            .GetExecutingAssembly()
            .GetTypes()
            .Single(type => !type.IsInterface
                        && handlerInterfaceConstructed.IsAssignableFrom(type))

        // Construct the concrete type
        ... argh ... stuck!
        
            
    }
    public async Task ExecuteCommandAsync(ICommand command)
    {
        // NEED TO FIND THE HANDLER THAT IMPLEMENTS ...
        // ... ICommandHandler<command type>
    }
}

How can I create an instance of the command handler that processes the command provided?





Aucun commentaire:

Enregistrer un commentaire