Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is DTO plus UnitOfWork pattern a good approach to design a DAL for a web application?

I'm implementing a DAL using entity framework. On our application, we have three layers (DAL, business layer and presentation). This is a web app. When we began implementing the DAL, our team thought that DAL should have classes whose methods receive a ObjectContext given by services on the business layer and operate over it. The rationale behind this decision is that different ObjectContexts see diferent DB states, so some operations can be rejected due to problems with foreign keys match and other inconsistencies.

We noticed that generating and propagating an object context from the services layer generates high coupling between layers. Therefore we decided to use DTOs mapped by Automapper (not unmanaged entities or self-tracking entities arguing high coupling, exposing entities to upper layers and low efficiency) and UnitOfWork. So, here are my questions:

  1. Is this the correct approach to design a web application's DAL? Why?
  2. If you answered "yes" to 1., how is this to be reconciled the concept of DTO with the UnitOfWork patterns?
  3. If you answered "no" to 1., which could be a correct approach to design a DAL for a Web application?

Please, if possible give bibliography supporting your answer.

About the current design:

The application has been planned to be developed on three layers: Presentation, business and DAL. Business layer has both facades and services

There is an interface called ITransaction (with only two methods to dispose and save changes) only visible at services. To manage a transaction, there is a class Transaction extending a ObjectContext and ITransaction. We've designed this having in mind that at business layer we do not want other ObjectContext methods to be accessible.

On the DAL, we created an abstract repository using two generic types (one for the entity and the other for its associated DTO). This repository has CRUD methods implemented in a generic way and two generic methods to map the DTOs and entities of the generic repository with AutoMapper. The abstract repository constructor takes an ITransaction as argument and it expects the ITransaction to be an ObjectContext in order to assign it to its proctected ObjectContext property.

The concrete repositories should only receive and return .net types and DTOs.

We now are facing this problem: the generic method to create does not generate a temporal or a persistent id for the attached entities (until we use SaveChanges(), therefore breaking the transactionality we want); this implies that service methods cannot use it to associate DTOs in the BL)

like image 494
JPCF Avatar asked Dec 29 '10 14:12

JPCF


People also ask

When should you use repository pattern?

The Repository pattern is used to decouple the business logic and the data access layers in your application. The data access layer typically contains storage specific code and methods to operate on the data to and from the data storage.

What are the advantages of repository pattern?

The Repository pattern makes it easier to test your application logic. The Repository pattern allows you to easily test your application with unit tests. Remember that unit tests only test your code, not infrastructure, so the repository abstractions make it easier to achieve that goal.

Do we need repository pattern with Entity Framework Core?

Developers building applications with ASP.Net Core and Entity Framework Core should not use UoW and Repository pattern anymore. EF Core supports unit testing and mock contexts.

What is repository pattern and unit of work?

The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application.


1 Answers

There are a number of things going on here...The assumption I'll make is that you're using a 3-Tier architecture. That said, I'm unclear on a few design decisions you've made and what the motivations were behind making them. In general, I would say that your ObjectContext should not be passed around in your classes. There should be some sort of manager or repository class which handles the connection management. This solves your DB state management issue. I find that a Repository pattern works really well here. From there, you should be able to implement the unit of work pattern fairly easily since your connection management will be handled in one place. Given what I know about your architecture, I would say that you should be using a POCO strategy. Using POCOs does not tightly couple you to any ORM provider. The advantage is that your POCOs will be able to interact with your ObjectContext (probably via Repository of some sort) and this will give you visibility into change tracking. Again, from there you will be able to implement the Unit of Work (transaction) pattern to give you full control over how your business transaction should behave. I find this is an incredibly useful article for explaining how all this fits together. The code is buggy but accurately illustrates best practices for the type of architecture you're describing: Repository, Specification and Unit of Work Implementation

The short version of my answer to question number 1 is "no". The above link provides what I believe to be a better approach for you.

like image 172
Jason Avatar answered Nov 15 '22 20:11

Jason