Click here to Skip to main content
15,881,424 members
Articles / Hosted Services / Azure

CQRS with Decoupled Messaging - Part III

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
4 Mar 2016CPOL3 min read 19.3K   1   5
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)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
PraiseNice article Pin
Doug Hieber17-Jun-16 4:05
Doug Hieber17-Jun-16 4:05 
QuestionAbout that refresh button... Pin
DaveVdE6-Mar-16 23:42
DaveVdE6-Mar-16 23:42 
AnswerRe: About that refresh button... Pin
Rishabh S Ajmera8-Mar-16 7:43
Rishabh S Ajmera8-Mar-16 7:43 
GeneralRe: About that refresh button... Pin
DaveVdE9-Mar-16 3:45
DaveVdE9-Mar-16 3:45 
GeneralRe: About that refresh button... Pin
Rishabh S Ajmera11-Mar-16 10:06
Rishabh S Ajmera11-Mar-16 10:06 
Here are views of Greg Young on Synchronous and Asynchronous command processing. The same video link that I had posted in the article. GregYoung video on CQRS
Listen to these portions in the video [3:06 for few minutes, and then 4:41 to 5:12].

This article assumes a fictitious "Inventory Management" system and assumed it to be collaborative domain and thus I had implemented asynchronous command processing.
In a real world the decision of whether or not the domain is collaborative would come about after coming to a common understanding with domain expert.

Just like command processing, event processing to update the read model can be synchronous or asynchronous. Typically it is asynchronous so that read model update happen separately and User does not have to wait for it to finish when command is issued. That is the option I took in this article.

This is where eventual consistency plays a role, as mentioned in Greg Young's video.
I am not a UI expert and UI was not the focus of this article, so I decided redirecting the user directly to the listing page.
In a real world, If I were to present this to business, initial proposal I would have would be to redirect the user to some kind of confirmation screen indicating that command was accepted for processing.
And on the same page providing more links for user to decide, where they want to go next,as mentioned in Greg Young's video. Since the application currently implements only a single Use case, I kept the UI simple and redirected them to List of inventory and gave a refresh button.

modified 11-Mar-16 16:18pm.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.