Custom Mediator Requests: Commands
In BlazorForKids, you can define your own business logic and data manipulation operations as Custom Mediator Commands. These requests follow the Mediator
pattern and are automatically integrated into the framework. This allows you to encapsulate logic such as updating a field, sending a notification, or applying validations — without cluttering your UI or service layers.
A command is used when you want to perform an action that modifies data or executes a business rule — for example: updating an email address, creating a task, approving a request, or generating a document.
How to Define a Custom Command
To create a custom command, follow these steps:
-
Create a class that inherits from
IBkRequest<IBkCommandResult>
. This defines the command and its return type. -
Inside that class, define a nested
Handler
class that implementsIBkRequestHandler<TCommand, IBkCommandResult>
. -
Implement the
Handle
method to define the actual logic to be executed.
Example: Updating an Employee's Email
publicclassUpdateEmployeeEmail(EmployeeIdid,stringemail):IBkRequest<IBkCommandResult>
{
privateEmployeeIdId{get;}=id;
privatestringEmail{get;}=email;
publicclassHandler(IBkMediatorDomainmediatorDomain):IBkRequestHandler<UpdateEmployeeEmail,IBkCommandResult>
{
publicasyncTask<IBkCommandResult>Handle(UpdateEmployeeEmailrequest,CancellationTokencancellationToken)
{
vareditModel=awaitmediatorDomain.EmployeeGetByIdQuery(request.Id,cancellationToken);
if(editModelisnull)
returnBkCommandResult.Warning("Employee not found");
editModel.Email=request.Email;
varresult=awaitmediatorDomain.EmployeeUpdateRequest(editModel,cancellationToken);
returnresult;
}
}
}
What the Framework Does for You
Once you define the command as shown above, the BlazorForKids framework automatically:
- Registers the command and handler with the dependency injection (DI) system.
-
Exposes the command method through the
IBkMediatorDomain
interface. -
Makes the method available in the
BkMediatorDomain
implementation — ready to be injected and called from anywhere (UI, background tasks, etc).
Generated Method in IBkMediatorDomain
publicinterfaceIBkMediatorDomain
{
Task<IBkCommandResult>UpdateEmployeeEmail(EmployeeIdid,stringemail,CancellationTokencancellationToken=default);
}
Generated Implementation in BkMediatorDomain
publicclassBkMediatorDomain
{
publicTask<IBkCommandResult>UpdateEmployeeEmail(EmployeeIdid,stringemail,CancellationTokencancellationToken=default)
{
returndispatcher.Send<UpdateEmployeeEmail,IBkCommandResult>(newUpdateEmployeeEmail(id,email),cancellationToken);
}
}
Where to Define Custom Commands
Custom commands must be defined inside the Domain project (usually in a Commands
folder).
Once defined, the request will automatically be discoverable and callable using the IBkMediatorDomain
interface.
How to Use a Custom Command
Anywhere in your application (for example, in a component or a service), inject the IBkMediatorDomain
interface and call your method:
publicclassEmployeeService(IBkMediatorDomainmediator)
{
publicasyncTaskUpdateEmailAsync(EmployeeIdid,stringnewEmail)
{
varresult=awaitmediator.UpdateEmployeeEmail(id,newEmail);
if(!result.Success)
{
// handle error or show message }
}
}
Command vs Query
The method shown above is for commands, which execute actions that change data. In contrast, a query is used to retrieve data. Both types of requests are supported in the framework and benefit from the same automatic registration and code generation.
We'll cover queries in the next section.