Entities VS Domain Models VS View Models

architecture asp.net-mvc c# design-patterns entity-framework

Question

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?

1
46
9/29/2018 9:39:24 AM

Popular Answer

I think you're just having issues with defining what each layer is and what role it is playing in your solution.


Data Tier

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
// ----------------------------

Data Access Layer

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.

Example...

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
// ----------------------------

Business layer

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.


Presentation tier

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


Cross cutting concerns

I'll keep this brief:

  • Exception management
  • Mapping of View Models to Domain Models.
101
5/23/2017 12:34:09 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow