65.9K
CodeProject is changing. Read more.
Home

CQRS with Decoupled Messaging Part V

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1 vote)

Mar 4, 2016

CPOL

2 min read

viewsIcon

18782

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

  • 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

  • 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.
    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:
    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