Skip to content

Command Scheduling

Commands are often designed to tell a system to do something. You don’t need a response other than “did it crash”. Commands offer additional capabilities such as deferred execution/scheduling and it is super simple to add!

  1. Create a command that implements IScheduledCommand (part of Shiny.Mediator.Contracts)

    public class MyScheduledCommand : IScheduledCommand
    {
    public DateTime DueAt { get; set; }
    }
  2. Create a standard command handler. Notice there is nothing special about this handler.

    public class MyScheduledCommandHandler : ICommandHandler<MyScheduledCommand>
    {
    public async Task Handle(MyScheduledCommand command, MediatorContext context, CancellationToken ct)
    {
    // do something with the command
    }
    }
  3. Follow all the steps to register the handler shown in Commands

  4. Register the command scheduling middleware in your AddShinyMediator registration

    services.AddShinyMediator(x => x.AddInMemoryCommandScheduling());
  5. Now, sends your command

    IMediator mediator;
    await mediator.Send(new MyScheduledCommand
    {
    DueAt = DateTime.UtcNow.AddMinutes(5)
    });

Custom Scheduling

In-Memory is fine for getting up and running. There are likely instances where you want this to survive across application restarts. We currently only offer an in-memory provider, but this is easily extendable to you now.

  1. Create a command scheduler by impleming Shiny.Mediator.ICommandScheduler (part of Shiny.Mediator)
    public class MyCommandScheduler : ICommandScheduler
    {
    public Task<bool> Schedule(IMediatorContext context, DateTimeOffset dueAt, CancellationToken cancellationToken)
    {
    // IMediatorContext contains all of the "stuff" you need
    mediator.Message; // object of your mediator contract
    mediator.MessageHandler; // the handler to call - HOWEVER: consider using context.Send
    // It is not recommended you use the cancellation token before STORING whatever data here as this is related to the WRITING of the call, NOT the run of the scheduled command
    }
    }
  2. Now register during your AddShinyMediator registration
    services.AddShinyMediator(x => x.AddCommandScheduler<MyCommandScheduler>());
  3. Now, when you send a command that implements IScheduledCommand, it will go through your scheduler
    IMediator mediator;
    await mediator.Send(new MyScheduledCommand
    {
    DueAt = DateTime.UtcNow.AddMinutes(5)
    });