Az Functions, CQRS & Mediatr

 

Azure functions

 

What are they?

Pieces of code that runs in the cloud!

 

Azure Functions is a serverless solution that allows you to write less code, maintain less infrastructure, and save on costs

 

Instead of worrying about deploying and maintaining servers, the cloud infrastructure provides all the up-to-date resources needed to keep your applications running.

C# | JavaScript | Java | Python | Rust |Go Power Shell

local Installation

A Trigger, as the name might imply, is an event that start the Azure Function

Bindings are a construct inside of an Azure Function that enables you to communicate with other services (Azure or external) .The bindings (both input and output) are passed to the Azure Function as a parameter when the function is executed.

Triggers & Bindings

Azure Functions types

examples

[FunctionName("HttpTriggerCSharp")]
public static Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req)
{
    ...
}
 [FunctionName("TimerTrigger1")]
 public void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
 {
	 log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
 }
[FunctionName("QueueTrigger1")]
public void Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")]
				string myQueueItem, ILogger log)
{
	log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
}

DEMO

  • Http Trigger
  • Timer Trigger
  • Queue Trigger

 

CQRS

Command query responsibility segregation

What is it?

CQRS stands for Command Query Responsibility Segregation and was coined by Greg Young. CQRS is related to CQS (Command Query Separation) principle by Bertrand Myer which states:

Every method should either be a command that performs an action, or a query that returns data to the caller, but not both.

where rest might fail

default version

multiple DBs version

Command-query separation (CQS) principle. It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both.

Advanced version

CQRS + REST SAMPLE

 

Mediatr

MediatR is a low-ambition library trying to solve a simple problem — decoupling the in-process sending of messages from handling messages.

Request/Response

The request/response interface handles both command and query scenarios. First, create a message:

public class Ping : IRequest<string> { }

Then create a handler:

public class PingHandler : IRequestHandler<Ping, string>
{
    public Task<string> Handle(Ping request, 
    				CancellationToken cancellationToken)
    {
        return Task.FromResult("Pong");
    }
}
var response = await mediator.Send(new Ping());
Debug.WriteLine(response); // "Pong"

Send the message:

Notifications

First create your notification message:

public class Ping : INotification { }

Next, create zero or more handlers for your notification:

public class Pong1 : INotificationHandler<Ping>{
    public Task Handle(Ping notification, CancellationToken cancellationToken){
        Debug.WriteLine("Pong 1");
        return Task.CompletedTask;}}

public class Pong2 : INotificationHandler<Ping>{
    public Task Handle(Ping notification, CancellationToken cancellationToken)    {
        Debug.WriteLine("Pong 2");
        return Task.CompletedTask;}}

Finally, publish your message via the mediator:

await mediator.Publish(new Ping());

Behaviors

They allow you to build your own pipeline directly inside of MediatR

public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    private readonly ILogger<LoggingBehavior<TRequest, TResponse>> _logger;

    public LoggingBehavior(ILogger<LoggingBehavior<TRequest, TResponse>> logger)
       => _logger = logger;
    

    public async Task<TResponse> Handle(TRequest request, 
   	CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
    {
        _logger.LogInformation($"Handling {typeof(TRequest).Name}");
        var response = await next();
        _logger.LogInformation($"Handled {typeof(TResponse).Name}");

        return response;
    }
}

D.I. registering Behaviors

        builder.Services.AddMediatR(typeof(GetTodosQuery).Assembly)
            .AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>))
            .AddTransient(typeof(IPipelineBehavior<,>), typeof(AuthBehavior<,>))
            .AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
  • Mediatr: (by Jimmy Bogard)is one of the most popular frameworks in the .NET community. It’s a simple framework that applies the concepts of CQRS without having to run an actual queue.

  • NServiceBus: (by Particular/Udi Dahan/) is a popular pub/sub library built by a company called Particular. It has an SLA.

  • MassTransit: Same as NServiceBus but open source and free.

  • Dapr.io: Distributed application runtime. A way to build applications that may be command/event driven.

mediatr & alternatives

DEMO

Thank you!

@imhotepp

2022

Made with Slides.com