0

I have a 3 layer architecture application with presentation layer, business layer and data access layer. UI -> BLL -> DAL UI Layer has reference to only BLL and BLL refer only to DAL.

My BLL has DTOs used by view and use service class that inject repository class from DAL and map DTOs to specific DAL entities for sending to repositories.

My DAL has one generic repository with all methods and use Dapper, and many entity repositories that implement generic repository, all repositories return directly entities, will be the service class that will map the entities to DTOs directly in BLL.

My Presentation layer will use services and will get DTOs for specific views.

I am using DTOs in a correct way?

Are correct the separation and references between layers?

Thanks in advance.

1 Answer 1

1

The question edges the opinionated answer because decoupling models belonging to layers of the same application (source code) is as legit as the opposite. It boils down to a matter of trade-offs and it should be driven by real needs.

If I'm allowed to opine (and I have built and worked on these kinds of applications), I would say, don't do it early. Don't create unnecessary barriers in your code, because it increases the complexity and, in this case, the verbosity too. It also makes the maintenance expensive and tedious.

Right now, you are assuming that business DTOs will cover all UI needs, but when they don't (and they won't sooner or later), you will add a 3rd type of DTO. So, every time you add a new table or change an existing one, you have to consider 3 different models and the layers they go through.

If your design is data centric and you have built verticals around tables1 and considering what I said, I would rather keep things simple.

Given these designs makes DAL to be the core of the application, I would consider allowing BLL to work with the DAL model2, and leave mappings (DTO) to the UI layer because it's the one that usually needs it.

The view is likely to change more often than business or persistence, it's also the layer you want to be as flexible as possible but you don't want UI needs driving your business and core. Even if you have no plan to support different views (desktop, browser, mobile, etc).

This said BLL might need (occasionally) custom inputs/outputs. That's fine. It's expected from the business to impose a contract and it's the outer-layers responsibility to respect it. In other words, do the mappings.

If at some point you are interested in more sophisticated layered designs, It might interest you to read about orthogonal designs and concepts like ports & adapters or dependency inversion.


1: 1 table, 1 Model, 1 repository [occasionally and 1 service]

2: business usually operates with the core, it's rare to decouple from it. I could be decoupled if the core is an absolute abstraction. I'm confident it's not the case

3
  • thanks for you response. So, you mean to add DTOs only from BLL to UI and BLL to interact directly with DAL entities? Nov 23, 2022 at 19:34
  • Sorry one question, method that not interact with all the entity, for example retrieve or update only some data should be in service layer or directly in repository? Nov 23, 2022 at 20:40
  • To the first question. No, DTOs belong to UI (or outer layers). BBL only works with domain entities and business entities/ports. To the second question: what to update is business logic and how to update/persist/fetch is the repository's logic.
    – Laiv
    Nov 24, 2022 at 9:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.