• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

De MediatR para Mediator: uma migração mais leve e performática

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,481
Баллы
155
*Dando continuidade à série sobre bibliotecas .NET que deixaram de ser open source e gratuitas, neste artigo apresento uma alternativa ao MediatR e explico por que ela pode representar uma migração mais leve em termos de estrutura e performance.

Desde que foi anunciado que o MediatR passará a adotar um modelo de licenciamento pago — mesmo que isso ainda leve algum tempo e a versão atual permaneça gratuita — nós, desenvolvedores, começamos a buscar alternativas próximas do que já conhecemos ou, em alguns casos, optamos por implementações próprias, como abordado no

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

sobre o AutoMapper.

Tendo isso em mente, encontrei uma alternativa — especialmente adequada para projetos que precisam ser migrados e para equipes já familiarizadas com o MediatR — que é o Mediator (com “o”). Assim como o anterior, ele implementa o padrão mediator e preserva as mesmas abstrações e recursos, já que foi desenvolvido com base no próprio MediatR.

Isso permite que atualizações em sistemas existentes ocorram de forma muito mais tranquila e rápida, além de facilitar sua adoção em novos contextos, já que a estrutura de implementação praticamente não se altera em relação ao que já estamos habituados a utilizar.

Um ponto especialmente relevante — e que me chamou bastante a atenção — é o foco do Mediator em performance. Isso se deve ao fato de sua implementação utilizar

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, um recurso introduzido no C# 9, em que, diferentemente do MediatR, que se baseia em reflexão para registrar e resolver seus handlers, é gerado código durante o tempo de compilação.

Isso não significa que a abordagem do MediatR seja ruim — muito pelo contrário. A reflexão utilizada por ele é altamente otimizada. No entanto, código gerado e compilado diretamente tende a oferecer desempenho consideravelmente superior em relação a soluções baseadas em reflexão.

Os benchmarks disponíveis na documentação do Mediator evidenciam um ganho significativo de performance em relação ao MediatR.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



Migrando do MediatR para o Mediator


A seguir, mostro um exemplo real de migração de um projeto baseado em MediatR para Mediator, destacando o que foi alterado.

1) Removendo o MediatR

Desinstale todas as referências ao pacote MediatR com o seguinte comando:


dotnet remove package MediatR

No projeto de exemplo, esse processo foi realizado em três Class Libraries.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



2) Instalando o Mediator

Adicione os pacotes do Mediator em substituição:


dotnet add package Mediator.SourceGenerator --version 3.0.*-*
dotnet add package Mediator.Abstractions --version 3.0.*-*

3) Ajustando os serviços

Altere a classe de configuração de dependências:


// Anterior
// using MediatR;

// Novo
using Mediator;

// Anterior
// services.AddMediator(c => c.RegisterServicesFromAssembly(typeof(Course).GetTypeInfo().Assembly));

// Novo
services.AddMediator((MediatorOptions options) => options.Assemblies = [typeof(Course)]);

4) Atualizando comandos, eventos e handlers

Command:



// Anterior
// using MediatR;

// Novo
using Mediator;

public abstract class CourseCommand : IRequest
{
// Propriedades e construtor inalterados
}

Event:


// Anterior
// using MediatR;

// Novo
using Mediator;

public sealed class RegisteredCourseEvent : INotification
{
// Propriedades, construtor e factory method inalterados
}

CommandHandler:


//Anterior
// using MediatR;

//Novo
using Mediator;

public sealed class CourseCommandHandler :
IRequestHandler<RegisterCourseCommand>,
IRequestHandler<UpdateCourseCommand>,
IRequestHandler<RemoveCourseCommand>
{
// Atributos e construtor inalterados

//Anterior
// public async Task<Unit> Handle(RegisterCourseCommand request, CancellationToken cancellationToken)

// Novo
public async ValueTask<Unit> Handle(RegisterCourseCommand request, CancellationToken cancellationToken)
{
// Lógica de negócio inalterada

// Anterior
// return await Unit.Task;

// Novo
return await Unit.ValueTask;
}

// Anterior
// public async Task<Unit> Handle(UpdateCourseCommand request, CancellationToken cancellationToken)

// Novo
public async ValueTask<Unit> Handle(UpdateCourseCommand request, CancellationToken cancellationToken)
{
// Lógica de negócio inalterada

// Anterior
// return await Unit.Task;

// Novo
return await Unit.ValueTask;
}

// Anterior
// public async Task<Unit> Handle(RemoveCourseCommand request, CancellationToken cancellationToken)

// Novo
public async ValueTask<Unit> Handle(RemoveCourseCommand request, CancellationToken cancellationToken)
{
// Lógica de negócio inalterada

// Anterior
// return await Unit.Task;

// Novo
return await Unit.ValueTask;
}
}

EventHandler:


// Anterior
// using MediatR;

// Novo
using Mediator;

public sealed class CourseEventHandler : INotificationHandler<RegisteredCourseEvent>
{
// Anterior
// public async Task Handle(RegisteredCourseEvent notification, CancellationToken cancellationToken)

// Novo
public async ValueTask Handle(RegisteredCourseEvent notification, CancellationToken cancellationToken)
{
// Exemplo para envio de e-mail quando o cliente se registrar em um curso
//notification.Emails.ForEach(e => SendMail(e));

// Anterior
// await Task.CompletedTask;

// Novo
await ValueTask.CompletedTask;
}
}

CourseAppService



// Anterior
// using MediatR;

// Novo
using Mediator;

public sealed class CourseAppService : ICourseAppService
{
// Atributos, construtor e métodos inalterados
}

⚠ Observação: Note que nos Handlers, o retorno dos métodos Handle mudou de Task para ValueTask.

Neste post, não vamos entrar em detalhes sobre o funcionamento do ValueTask, mas, de forma resumida, trata-se de uma struct que pode evitar alocação de memória heap, reduzindo a pressão sobre o Garbage Collector e sendo mais eficiente em cenários onde a operação assíncrona é concluída rapidamente.

Você pode ver as alterações e o projeto de exemplo completo no

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.

Conclusão


O Mediator se mostra uma alternativa viável, leve e altamente compatível com a abordagem que o MediatR já entregava.

Sua estrutura familiar, aliada ao uso de Source Generators, torna a migração simples e vantajosa em termos de performance e manutenção. Para quem está reavaliando o futuro da stack de desenvolvimento .NET, vale a pena considerar o Mediator.

E você, já migrou ou ainda está avaliando como fazer a transição? Compartilhe sua experiência nos comentários.

Até o próximo artigo!

Precisa de apoio para decidir o futuro dos seus projetos — manter, evoluir ou começar do zero?

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


Nosso time de especialistas está pronto para ajudar você a enfrentar esses e outros desafios tecnológicos.


Referências



Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу