I know there is a similar topic already, but not sure how similar so I’ll try to post a bit more details about the architecture POC I’m asked to do.
I’m trying to build a POC for a new system based built on top of modular monolith architecture using NServiceBus for integration (comm between the modules). Modular monolith is mandatory since the product owner does not feel this should be using microservices architecture just yet, he wants to keep it simple as possible, but also as the product matures and userbase grows, it needs to be “convertible” to microservices (scale out).
Anw, POC so far implements loosely coupled modules, which can be easily converted to standalone apps. Every module has its own composition root, settings etc. And main initialization of the modules is handled in one API project.
As for integration, we would like to use NServiceBus, having one endpoint (bidirectional) per module. The only thing that is shared between modules is ModuleName.Integration class lib projects with messages, commands, and events.
The initial draft idea was to have one endpoint console application per module (acting as both receiver and sender) and every endpoint has its own configuration. As this is still a monolith where everything is hosted under one host or web application, we would still rather use multi-hosting by using web jobs under one app service plan, if it is possible. I do realize we need to be careful to scope assembly scanning by endpoint instance and probably set DI containers per instance.
For this, we would use only SQL Server Transport and modules are built in such a way that every module uses its own database so the plan was to use a module database for module-specific endpoint transport and persistence with transaction mode set to TransactionScope. So every endpoint would have its own queues in a module-specific database.
The flow would be that module feature handlers handle both API requests > business data (saving to DB) and publishing of events (transactional). Any NserviceBus handler subscribed to a certain event would also use module-specific features if needed to handle business data. All routing settings would be provided in the bootstrapping API to all endpoint configuration instances.
Any comments or suggestions would be appreciated for this POC theory for now (integration part), are we missing something, does it makes sense at all to go down that path, to keep endpoints in a bounded context per module? Or it would make more sense just to use one endpoint for all modules and reference them and the messages to that one endpoint. Anw, the product owner would like to use NServiceBus for an integration solution, we already used it in a couple of simpler projects, including Sagas and other functionalities.