0Pricing
C# Academy · Урок

Команды и обработчики с MediatR

Направляйте запросы специализированным обработчикам.

«Команды и обработчики с MediatR» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.

Регистрация MediatR

MediatR сканирует сборки, чтобы обнаружить обработчики. Зарегистрируйте его один раз при запуске, указав сборку, содержащую обработчики.

builder.Services.AddMediatR(cfg =>
    cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));

Интерфейс запроса

Сообщение, ожидающее ответа, реализует IRequest<TResponse>. Параметр типа определяет, что возвращает handler.

public record CreateOrderCommand(int CustomerId, string[] Items)
    : IRequest<int>;   // returns the new order id

Команды без результата

Если команда не возвращает содержательных данных, реализуйте обобщённый интерфейс IRequest (это сокращённая запись для IRequest<Unit>).

public record CancelOrderCommand(int OrderId) : IRequest;

Интерфейс обработчика запроса

Handler реализует IRequestHandler<TRequest, TResponse> и предоставляет метод Handle, в котором выполняется работа.

public class CreateOrderHandler
    : IRequestHandler<CreateOrderCommand, int>
{
    public Task<int> Handle(
        CreateOrderCommand request, CancellationToken ct)
    {
        // create the order...
        return Task.FromResult(newOrderId);
    }
}

Внедрение зависимостей

Обработчики извлекаются из DI, поэтому они могут получать через конструктор контекст context базы данных, репозитории и другие службы.

public class CreateOrderHandler(AppDbContext db)
    : IRequestHandler<CreateOrderCommand, int>
{
    public async Task<int> Handle(
        CreateOrderCommand request, CancellationToken ct)
    {
        var order = new Order { CustomerId = request.CustomerId };
        db.Orders.Add(order);
        await db.SaveChangesAsync(ct);
        return order.Id;
    }
}

Отправитель

Чтобы отправить запрос, внедрите ISender (или более общий IMediator) и вызовите Send. MediatR найдёт подходящий handler.

public class OrdersController(ISender sender) : ControllerBase
{
    [HttpPost]
    public async Task<IActionResult> Create(CreateOrderCommand cmd)
    {
        int id = await sender.Send(cmd);
        return CreatedAtAction(nameof(Get), new { id }, null);
    }
}

Отправка в минимальных API

Минимальные API внедряют ISender непосредственно в делегат конечной точки.

app.MapPost("/orders", async (
    CreateOrderCommand cmd, ISender sender) =>
{
    var id = await sender.Send(cmd);
    return Results.Created($"/orders/{id}", new { id });
});

Запросы — это тоже сообщения

Запросы используют тот же механизм IRequest / IRequestHandler; различается только намерение: handler читает данные и никогда их не изменяет.

public record GetOrderQuery(int Id) : IRequest<OrderDto?>;

public class GetOrderHandler(AppDbContext db)
    : IRequestHandler<GetOrderQuery, OrderDto?>
{
    public async Task<OrderDto?> Handle(
        GetOrderQuery q, CancellationToken ct) =>
        await db.Orders
            .Where(o => o.Id == q.Id)
            .Select(o => new OrderDto(o.Id, o.Total))
            .SingleOrDefaultAsync(ct);
}

Один обработчик на запрос

Для Send типу запроса должен соответствовать ровно один handler. Наличие нуля или двух обработчиков для одного запроса — ошибка конфигурации.

// CreateOrderCommand -> exactly one CreateOrderHandler

Возврат содержательных результатов

Ответ может иметь любой тип — объект передачи данных, оболочку результата или даже результат с несколькими вариантами, — позволяя обработчикам явно выражать успех и неудачу.

public record Result(bool Ok, string? Error);
public record PlaceOrderCommand(int Id) : IRequest<Result>;

Тестирование обработчика

Поскольку handler — это обычный класс с внедрёнными зависимостями, его можно тестировать напрямую: без HTTP и без контроллера.

var handler = new CreateOrderHandler(inMemoryDb);
var id = await handler.Handle(
    new CreateOrderCommand(1, ["sku-1"]), CancellationToken.None);
Assert.True(id > 0);

Быстрая проверка

Проверьте, понимаете ли Вы модель отправки MediatR.

Итоги

Вы реализовали команды и обработчики:

  • AddMediatR сканирует сборки и регистрирует обработчики.
  • Сообщения реализуют IRequest<T>, а обработчики — IRequestHandler<TRequest, T>.
  • Внедрите ISender и вызовите Send для отправки сообщения; ему соответствует ровно один handler.
  • Запросы используют тот же механизм и не имеют побочных эффектов.

Далее: поведения конвейера.

Часто задаваемые вопросы

Урок «Команды и обработчики с MediatR» бесплатный?

Да — полный текст урока «Команды и обработчики с MediatR» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.

Чему я научусь в уроке «Команды и обработчики с MediatR»?

Направляйте запросы специализированным обработчикам. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C# Academy?

Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Команды и обработчики с MediatR»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C# Academy?

Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Концепции CQRS
  2. Команды и обработчики с MediatR
  3. Поведения конвейера
  4. Уведомления и события
← Назад к C# Academy