mercredi 8 septembre 2021

Casting to unknown derived type at runtime?

I've got this command bus implementation which is typically called like this:

bus.Invoke(new FocusCommand());

This works fine, but there's now a situation where the command is dynamic:

// Command to invoke is resolved at runtime.
Command parsedCommand = ParseCommand(input);
bus.Invoke(parsedCommand);

The simplified bus and command implementation looks something like this:

public class Command
{
}

public interface ICommandHandler<TCommand> where TCommand : Command
{
  void Handle(TCommand command);
}

public class FocusCommand : Command
{
}

public class FocusHandler : ICommandHandler<FocusCommand>
{
  public void Handle(FocusCommand command) { ... }
}

public class Bus
{
  // Sends command to appropriate command handler.
  public void Invoke<T>(T command) where T : Command
  {
    // In real application, this gets the handler instance from the DI framework
    // using `Provider.GetRequiredService`, which always returns an `object`.
    object handlerInstance = GetHandlerInstanceForCommand(command);

    return (handlerInstance as ICommandHandler<T>).Handle(command); // <--- Error is thrown here in 2nd case.
  }
}

In the 2nd use case it gets the correct handlerInstance, but casting handlerInstance as ICommandHandler<T> just become null and it throws System.NullReferenceException 'Object reference not set to an instance of an object.'

Is the way to solve this to somehow cast the parsedCommand to the derived type at runtime?

Added a short runnable example of the issue here https://gist.github.com/lars-berger/f16f504938c592432be0f996b8fd9cfa





Aucun commentaire:

Enregistrer un commentaire