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

CQRS with Decoupled Messaging Part V

5.00/5 (3 votes)
4 Mar 2016CPOL2 min read 18.8K  
Fifth and final post in a 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 with focus on Read side. 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.

Code for Inventory Manager Application is on GitHub Repository - Located here

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
  4. Inventory Manager - CQRS application (with decoupled messaging) - Aggregate and Event Sourcing
  5. Inventory Manager - CQRS application (with decoupled messaging) - ReadSide (this article)

ViewModel Generator

Image 1

  • In the worker role, viewmodel generator handles the event InventoryCreated, as we saw in last article.
  • The handler works with the ReadModel and creates a new inventory and saves it in database on Read side.
  • Database on the Readside is Code-first EF SQL database.

Read Side

Image 2

  • The website reads data from Read Database, using thin data access layer and shows it in MVC View.

Use of Func<> in IOC

  • An interesting thing to bring to attention was how Func<> is used in the thin Data layer for Read side.
  • HomeController calls upon InventoryItemsDao to retrieve list of all inventory items.
    C#
    public class HomeController : Controller
    {
        private readonly IServiceBus _bus;
        private readonly InventoryItemsDao _inventoryItemsDao;
    
        public HomeController()
        {
            _bus = IoC.Resolve<IServiceBus>();
            _inventoryItemsDao = IoC.Resolve<InventoryItemsDao>();
        }
    
        public ActionResult Index()
        {
            var inventoryItems = _inventoryItemsDao.GetAllInventoryItems();
            return View(inventoryItems);
        }
        
        // .. Code
    }
  • There were no registrations done for InventoryItemsDao, with IoC. So IoC will try to create an instance of the class trying to resolve any dependencies that it may have provided in its constructor.
  • InventoryItemsDao has constructor as follows:
    C#
    public class InventoryItemsDao
    {
        private readonly Func<InventoryManagerDbContext> _contextFactory;
    
        public InventoryItemsDao(Func<InventoryManagerDbContext> contextFactory)
        {
            _contextFactory = contextFactory;
        }
    
        public IList<InventoryItem> GetAllInventoryItems()
        {
            using (var context = _contextFactory.Invoke())
            {
                return context
                    .Query<InventoryItem>()
                    .ToList();
            }
        }
    }
  • The InventoryManagerDbContext has a default constructor, thus it did not have to be registered with IoC container.
  • IoC allows us to specify dependency in a Func return argument and resolves the dependency when one calls invoke on the Func. Click here for more information.

Conclusion

  • This covers up the code walkthrough of Inventory Manager Application. I hope you found the post interesting.
  • The code is still a proof of concept and I will post updates to the solution as I use it. However, it surely can serve as a good playground for trying out CQRS in a practical application.
  • Any feedback on the article is welcome and thanks for your patience.
  • For a complete list of articles in this series, please go to the Introduction section of this article.

References

  1. Super simple cqrs” example by Greg Young

License

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