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
Handlerclass that implementsIBkRequestHandler<TCommand, IBkCommandResult>. -
Implement the
Handlemethod 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
IBkMediatorDomaininterface. -
Makes the method available in the
BkMediatorDomainimplementation — 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.