Our business works with truck drivers making pickups/deliveries of containers. The location of containers needs to be tracked.
The drivers use mobile devices to generate a “DriverReport” (a log of their trip locations, times, container pickup/drop-offs, etc.). This is currently working with a mostly CRUD design.
We wanted to maintain good SoC so we built two services:
- DriverService
- InventoryService
We’ve had the DriverService take a dependency on the InventoryService. When a new DriverReport was inserted, it would generate DTO’s (based off the reports data) that could be sent to the InventoryService.
We’re not using CQRS yet, but we’re considering transitioning to it.
I’m struggling to understand the relationship between the services, commands and BLL. I seem to have lots of questions.
Who would be responsible for calling the inventory service?
Would it be good design for a NewTripCommandHandler to generate and send an UpdateContainerInventory command?
Or, would updating inventory for a new Trip be considered business logic? If yes, should a a domain entity for Trip generate and send an UpdateContainer command?
Or, should the mobile client generate both trip and inventory specific commands to send to the appropriate service?
Would it make more sense to take the parts specific to DriverReport inventory and merge it into the DriverService (so the dependency is broken)? Is that still good SoC? If we did this, at what layer might we start to think about the inventory? Would updating the inventory simply become a DB repository concern, or should there still be inventory specific commands and/or business logic?
I’m getting lost in the details, and it seems the more I read on the topics, the more confused I get.
You could consider SOA if you want to. The thing is here you’re only dealing with Commands. If you add the Publish/Subscribe pattern (message queues, service bus), you can have the serives publish events/messages, and not have to know who the subscribers were; the subscribers would all get the news and operate off the message contents.
My advice is to stop thinking about services, commands and fancy terms in OO design.
I would strongly recommend modelling your business logic without thinking about service oriented architecture, how the data will be transferred from clients to the service, etc.
You have an application. Your application clearly has two modules:
-
Module for processing a driver’s report. I really don’t care how this report gets generated and where the data comes from at this stage.
-
Module for updating inventory. Now I would not create a dependency between driver’s report and inventory processing. Instead I would create a component that would extract relevant data from the driver’s report and then pass it into the inventory processing module.
Once all this is in place I would start thinking about services (boundaries). I’d be asking questions like “Does it really make sense to create an inventory service? Will I have a client application that will call it directly?”
Finally, I would question having any business logic in the client application. I normally model and unit test all my business requirements in the domain layer. Once that’s done, I start working on the client application. This way my client application is pretty dumb, all it does is aggregate some data, pass it to the domain layer, lets domain layer work out what to do with the data, and then finally display result back to the user.
Update 1
So instead of:
var driverReport = new DriverReport();
var inventoryCoordinator = new InventoryCoordinator();
inventoryCoordinator.Process(driverReport);
I would have:
var driverReport = new DriverReport();
var inventoryUpdate = InventoryUpdateFactory.Create(driverReport);
var inventoryCoordinator = new InventoryCoordinator();
inventoryCoordinator.Process(inventoryUpdate);
In first example the inventory coordinator has a direct dependency on drivers’ report.
In second example, we extract relevant information from the drivers’ report and then pass that into inventory coordinator for further processing.
4