From The Official Guide - Mastering ABP Framework, Chapter 15 Working with Modularity, page 416, there are 4 isolation levels for an applicaion module defined in the book, one of them called 'Bounded contexts' and it's definition is as below:
A module can be part of a large monolith application, but it hides its internal domain objects and database tables from other modules. Other modules can only use its integration services and subscribe to the events published by that module. They can't use the database tables of the module in SQL queries. The module may even use a different kind of DBMS for its specific requirements. That is the bounded context pattern in domain driven design. Such a module is a good candidate to convert to a microservice if you want to convert your monolith application to a microservice solution in the future.
My question is: An ABP application module solution is formed by several projects, for example:
- Application
- Application.Contracts
- Domain Domain.Share
- EntityFrameworkCore
- HttpApi
- HttpApi.Host
- Web
As we known, each of those project will be compiled to an individual assembly, so how can i achieve 'The module should hides its internal domain objects and database tables from other modules'?
For a microservice, a bounded context is isolated in the application level, so it still can use the 'public' modifier to declare the aggregate root or other entities and then the application layer can use them. But a bounded context as a application module will be referenced by other modules or applications, once been referenced, all the public members can be directly use, how can I make them 'invisible' to other modules but at the same time 'visible' to the application layer inside??
One way i think of is to use the ‘internal’ modifier to declare all the entities, Aggreget roots and all other domian objects, but in that case, the Application layer will not be able to use the objects from the domain layer as well. so to overcome that, i need to combined the application layer and domain layer into a single project, but doing this really makes me feel very inelegant, and the most harmful side-effect is that the entities inside the aggregate will exposed to the application layer.
I can't find any example from the official guid and the website docs, is there any 'best practice' around?