Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Hosted-services / Azure

CQRS with Decoupled Messaging - Part III

5.00/5 (3 votes)
4 Mar 2016CPOL3 min read 20.4K  
Third post in series of articles that show practical application of CQRS architecture with emphasis on decoupling messaging as infrastructure component

Introduction

In this article, we will look at Inventory Manager Application which is following CQRS architecture with decoupled messaging infrastructure component that was built in the previous article. Use cases for Inventory Manager are based on “Super simple cqrs” example by Greg Young. In Inventory Manager, only the first use case of creating an inventory item has been implemented.

Note that this post is part of series of articles, links for all the articles in the series are provided below:

  1. Introduction
  2. Need for Enterprise Servicebus Frameworks and Decoupled messaging with their samples
  3. Inventory Manager - CQRS application (with decoupled messaging) - Commands (this article)
  4. Inventory Manager - CQRS application (with decoupled messaging) - Aggregate and Event Sourcing
  5. Inventory Manager - CQRS application (with decoupled messaging) - ReadSide

Inventory Manager

Code for this application is on GitHub Repository - Located Here.

The technology stack used is as follows:

  • Azure web and worker roles
  • MassTransit (version 2.9.9) with Azure service bus
  • Azure Storage – Table for storing events
  • The Inventory Manager also uses IServicebus abstraction, which was explained in the previous articles.

User Experience

  • Only the First Use case for creating an inventory has been implemented
  • Thus we have 2 screens, one that shows list of inventory items and the other that allows adding inventory.

    Image 1

  • When user clicks on “Add New Inventory”, he will be redirected to the following screen where name of the inventory is asked.

    Image 2

  • Once user clicks “Add” button, command message is fired and then he is redirected to listing screen.
  • The command is then processed by the worker process, which may take time after which the user can see the updated list. Thus a "Refresh" button has been provided on the Listing screen.
  • This is following the PRG pattern.

Running the Application

  • Specify values for azure namespace and azure service bus key in the following config files:
    • Web.config in InventoryManager.Web project
    • App.config in InventoryManager.Worker project
    XML
    <appSettings>
      <add key="azure-namespace" value="" />
      <add key="azure-key" value="" />
    </appSettings>
    
  • Also the Read model is persisted in database. Application is using Code-first approach with EntityFramework on Read side with SQL server. So the database will be created by itself in SQL Server. A named instance of SQL Server is required “.\SQLExpress” with a SQL user “InventoryManagerReadDbUser” that has dbcreator Role. If need be, one can change the connectionstring to suit their needs. It is present with name “InventoryManagerDbContext” in both Web and Worker projects.

Web Role

Project Dependencies

Image 3

Responsibilities

  • Web Role works with the IServicebus interface and fires off commands from the Web Controllers upon user actions.
    C#
    public class HomeController : Controller
    {
        private readonly IServiceBus _bus;
        // .. Code
    
        public HomeController()
        {
            _bus = IoC.Resolve<IServiceBus>();
            //.. Code
        }
    
        // .. Code
    
        [HttpPost]
        public ActionResult Add(string name)
        {
            _bus.Send(new CreateInventoryItem(Guid.NewGuid(), name));
            return RedirectToAction("Index");
        }
    }
  • Controller and Web Role are also on the Read side, so it accesses the Read Model via simple DataAccess layer to fetch data and show it in web page.

Worker Role

Project Dependencies

Image 4

Responsibilities

We will be looking at the implementation of some of these in the next article. Worker Role also uses the IServicebus interface for subscribing to commands, publishing and subscribing to events.

  • Handling the command
  • Calling behavior on the domain, Aggregate
  • Persisting EventSourced Aggregate, i.e., events in EventStore
  • Publishing Events upon save of Aggregate, ensuring that save and publish happen in atomic manner
  • Providing handler for the published event and updating the Read Model in the handler

Next Article in the Series

The next article in the series will focus on Aggregate and Eventsourcing in Inventory Manager application.

For a complete list of articles in this series, please go to the Introduction section of this article.
Thanks for reading the articles, hope they are proving insightful.

References

  1. Super simple cqrs” example by Greg Young
  2. PRG Pattern

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)