I have a 3-tiered application
DAL has EDMX file that EF6 generated it automatically from database (DB First mode). I have BLL and UL layers too.
But, when I want to use BLL methods in UI, I must add DAL assembly to UI layer (because of return types of methods)
List<Person>
Person define in EDMX (DAL)] (this my problem)
How I can separate classes (DTO) from EDMX file and create as separate assembly?
How can I prevent adding DAL Assembly (whole EDMX) to the UI layer?
The DTO layer itself is designed to be highly decoupled, so that the generated assemblers, DTOs, repositories and even services can be easily used outside of the generated service.
DTOs provide an efficient way to separate domain objects from the presentation layer. This way, you can change the presentation layer without affecting the existing domain layers, and vice versa.
A DTO is an object that defines how the data will be sent over the network. Let's see how that works with the Book entity. In the Models folder, add two DTO classes: C# Copy.
Data Transfer Objects are used to transfer data between the Application Layer and the Presentation Layer. The Presentation Layer calls an Application Service method with a Data Transfer Object (DTO).
Here is what I would do. To decouple the DAL from the UI, you will need a "middle tier". Consider the following diagram.
The middle tier is widely know as the service layer or the application layer.
Everytime the Person
data passes from one layer to another, it is "mapped" to its equivalent class for that specific layer.
The following snippets makes up the very basic example of a service layer. I did not include the other details such as AutoMappers and other general practices.
The PersonDto
, defined in the middle tier, represents the Person
entity.
public class PersonDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
The PersonService
class. It encapsulates the data access and business logic, and returns only the PersonDto
(instead of the entities). It is how the UI communicates with the domain.
public class PersonService
{
public PersonDto GetPersonById(int id)
{
Person person = dbContext.Persons.Find(id);
// Mapping in action.
var personDto = new PersonDto()
{
FirstName = person.FirstName,
LastName = person.LastName,
};
return personDto;
}
}
This PersonService
is what the UI code sees, it does not know about the data access or the business logic. It only knows about the services.
The services should encapsulate your business logic, decoupling the UI from the BLL and DAL.
Good question, the accepted wisdom is that you define a different Person for each tier/layer (DAL, BLL and UI) and then write code to map between each layer. There's AutoMapper which can make life easier.
Now consider a real-life application with 100 to 1,000 entities. This pattern does not scale well.
I suggest using the Code First approach to EF. And passing the same object between all your layers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With