Saturday, 11 November 2023

CQRS pattern

CQRS, or Command Query Responsibility Segregation, is a design pattern that separates the responsibilities of reading and writing data in a software system. Here’s a breakdown of its key concepts:

Key Concepts

  1. Separation of Concerns:

    • Commands: These are actions that change the state of the system (e.g., creating, updating, or deleting data). They do not return data.
    • Queries: These are operations that retrieve data without altering the system’s state. They are designed for read operations.

Here's a simple example of implementing the CQRS pattern in C#:

 // Command
public class CreateProductCommand
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// Command Handler
public class CreateProductCommandHandler
{
    public void Handle(CreateProductCommand command)
    {
        // Logic to create a new product and update the state
        // This might involve validation, persistence, and other business logic

        Console.WriteLine($"Product '{command.Name}' created successfully with price {command.Price}");
    }
}

// Query
public class GetProductQuery
{
    public int ProductId { get; set; }
}

// Query Handler
public class GetProductQueryHandler
{
    public Product Handle(GetProductQuery query)
    {
        // Logic to retrieve product information from the state
        // This might involve querying a database, caching, or other mechanisms

        return new Product
        {
            ProductId = query.ProductId,
            Name = "Sample Product",
            Price = 29.99m
        };
    }
}

// Model
public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// Example Usage
class Program
{
    static void Main()
    {
        // Command side usage
        var createProductCommand = new CreateProductCommand
        {
            Name = "Example Product",
            Price = 49.99m
        };

        var createProductHandler = new CreateProductCommandHandler();
        createProductHandler.Handle(createProductCommand);

        // Query side usage
        var getProductQuery = new GetProductQuery
        {
            ProductId = 1
        };

        var getProductHandler = new GetProductQueryHandler();
        var product = getProductHandler.Handle(getProductQuery);

        Console.WriteLine($"Product Name: {product.Name}, Price: {product.Price}");
    }
}

In this example, the CreateProductCommand represents a command for creating a new product, and the CreateProductCommandHandler handles this command, updating the system state accordingly. On the query side, the GetProductQuery represents a query to retrieve product information, and the GetProductQueryHandler handles this query, providing the necessary data from the system state. The Product class is a simple model representing a product.

Benefits:

  • Scalability: By separating reads and writes, you can optimize each side independently. For instance, you might use different data stores or caching mechanisms for reading.
  • Performance: Read and write models can be tailored for their specific tasks, potentially improving performance.
  • Flexibility: Allows for different data models for reads and writes, which can simplify complex domains.

Reference: https://www.c-sharpcorner.com


0 comments:

Post a Comment

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (47) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (49) CD (1) CI (2) CloudComputing (2) Coding (8) CQRS (1) CSS (2) Design_Pattern (7) DevOps (4) DI (3) Dotnet (10) DotnetCore (19) Entity Framework (4) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (10) microservice (4) Mongodb (1) MVC (46) NodeJS (8) React (10) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (3) UI (1) UnitTest (2) WCF (14) Web Api (16) Web Service (1) XMl (1)

Dotnet Guru Archives