There are hundreds of similar questions on this topic. But I am still confused and I would like to get experts advise on this.
We are developing an application using ASP.NET MVC 4 and EF5 and ours is DB first approach.
We have Data layer in a separate project which is a class library and holds all the Entities defined in it. And then Business Layer defined with all the repositories and domain models(is that right term to be used). And then comes presentation layer.
At present we have not defined any view models, we are using the same domain models from BL as view models. In this approach one mapping can be enough.
ENTITY <=> DOMAIN MODEL
But for me it's not looking like a good design. I prefer to have view models defined in my presentation layer and use domain models to communicate between presentation layer and business layer. And at BL, convert domain objects to data entities and communicate with DAL. Using this approach I have to use mapping twice.
View Model <=> DOMAIN MODEL <=> ENTITY
Is my domain model really necessary? Can't I use my entity to communicate with Presentation layer. Are there any impacts if I am referencing Entities in my presentation layer? If there are what kind of impacts?
In practical purpose, domain and model are the same, while entity is also a domain/object that would be used to store in the database. Some people are tried to re-explain such topics but none of them are canon.
Entity: An entity represents a single instance of your domain object saved into the database as a record. It has some attributes that we represent as columns in our tables. Model: A model typically represents a real world object that is related to the problem or domain space.
A model is usually more closely related to how your data is stored (database, services, etc.) and the model will closely resemble those. The ViewModel on the other hand is closely related to how your data is presented to the user. It is usually a flatten version of your model, denormalized, etc.
Entities represent domain objects and are primarily defined by their identity, continuity, and persistence over time, and not only by the attributes that comprise them.
I think you're just having issues with defining what each layer is and what role it is playing in your solution.
Your data tier is simply your database / SharePoint list / .csv file / excel sheet... you get the idea, it's simply where your data is stored, and it can be in any format. So remember that the data tier is nothing more than just data.
// ---------------------------- // Data tier // - MySQL // - MS SQL // - SharePoint list // - Excel // - CSV // - NoSQL // ----------------------------
This layer abstracts away your data source, and provides an API in which the rest of your application can interact with the data source.
Consider that our data source is an MS SQL Database and that we're using Entity Framework to access the data. What you'll be attempting to abstract away, is the database and Entity Framework, and have a Data Repository
for each Entity
.
We have a Customers
table in a MS SQL Database. Each customer in the customers table is an Entity
, and is represented as such in your C# code.
By using the repository pattern, we can abstract away the implementation of the data access code, so that in future, if our data source changes, the rest of our application wont be affected. Next we would need a CustomersRepository
in our Data Access Layer
, which would include methods such as Add
, Remove
and FindById
. To abstract away any data access code. The example below is how you would achieve this.
public interface IEntity { int Id { get; set; } } public class Customer : IEntity { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime RegistrationDate { get; set; } } public interface IRepository<TEntity> where TEntity : class, IEntity { TEntity FindById(int id); void Add(TEntity entity); void Remove(TEntity entity); } public class CustomerRepository : IRepository<Customer> { public Customer FindById(int id) { // find the customer using their id return null; } public void Add(Customer customer) { // add the specified customer to the db } public void Remove(Customer customer) { // remove the specified customer from the db } }
The data access layer belongs in between the data layer and business logic.
// ---------------------------- // Business logic // ---------------------------- // ---------------------------- // Data access layer // - Repository // - Domain models / Business models / Entities // ---------------------------- // ---------------------------- // Data tier // - MySQL // - MS SQL // - SharePoint list // - Excel // - CSV // - NoSQL // ----------------------------
The business layer is built on top of the data access layer, and does not deal with any data access concerns, but strictly business logic. If one of the business requirements was to prevent orders being made from outside of the UK, then the business logic layer would handle this.
The presentation tier simply presents your data, but if you're not careful about what data you present, and what data you allow to be posted, you'll set your self up for a lot of headaches down the line, which is why it's important to use view models, as view models are a presentation tier concern, the presentation tier doesn't need to know anything about your domain models, it only needs to know about view models.
So what are View Models... They're simply data models which are tailored for each view, for example a registration form would include a RegistrationViewModel
, exposing these typical properties.
public class RegistrationViewModel { public string Email { get; set; } public string Password { get; set; } public string ConfirmPassword { get; set; } }
The presentation tier also handles input validation, so for instance validating whether an email address typed has the correct format, or that the passwords entered match is a presentation tier concern, not a business concern, and can be handled by using Data Annotations
.
public class RegistrationViewModel { [Required] [DataType(DataType.EmailAddress)] public string Email { get; set; } [Required] [DataType(DataType.Password)] [Compare("ConfirmPassword") public string Password { get; set; } [Required] [DataType(DataType.Password)] public string ConfirmPassword { get; set; } }
The reason it's important to use View Models is because the Business Models belong to the business layer, and they include data which should remain private. For instance, if you were to expose the Domain Model in a JSON response, it would expose the users entire data, their name their address as you're not being selective about what is being exposed and what isn't, but using whatever that seems to be working.
I should also point out here that there is a difference between domain models
and entity models
. There's already an answer that goes into a lot more detail here
I'll keep this brief:
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