How to organize dependencies in 3-tier architecture

658 views Asked by At

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?

2

There are 2 answers

0
wblanks On BEST ANSWER

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.

0
Zoran Regvart On

You could introduce a fourth module common to all that has all interfaces and domain model, but that won't prevent REST calling DAL directly (it will compile at least).

I usually do it like that or go straight for the first option, and I don't worry about that as I'm counting on the my other co-conspirator developers to have some sense of architecture separation. I've in the past used 'architectural' aspects to prevent layer hopping, but you'd have to include aspect compiler support in your build/IDE to do that.