I am starting project which will use 3-tier architecture with REST API.
I would like to split each layer into separate module, so I definitely need at least 3 modules:
- REST
- BLL
- DAL
What is the best approach to make dependencies between them:
1)
- REST depends on BLL
- BLL depends on DAL
- DAL depends on nothing
2)
- REST depends on nothing
- BLL depends on REST
- DAL depends on BLL
3)
- REST depends on REST-BLL-Interfaces
- REST-BLL-Interfaces depends on nothing
- BLL depends on REST-BLL-Interfaces and DAL-BLL-Interfaces
- DAL-BLL-Interfaces depenends on nothing
- DAL depends on DAL-BLL-Interfaces
Third approach seems to be the most compatible with Dependency Inversion Principle but requires more modules. How would You name those two additional modules?
I would keep your BLL code in a project called Services, your DAL code in a project called Repositories, and your interfaces and business objects(or entities) in a project called Core.
Your REST project should reference only Core (and Services for resolving dependencies). You program exclusively to interfaces. You can also employ the DI Principle here, as you stated.
Your Services and Repositories should each only depend on Core. These concrete implementations need only implement Core interfaces and act on Core entities.
Not only does this approach allow you to use DI, but it makes testing much easier. Additionally, none of your application will be tightly coupled to your concrete external dependencies (ie, a particular database implementation). This makes your entire application much more flexible and extensible.
Side note: I often include another project called Infrastructure to handle cross-cutting concerns such as logging. These concrete classes implement Core interfaces, just like my repositories and services, and can be called using interfaces.