What is the best way to create a view model?

I am using asp.net mvc with an entity framework and am starting to learn DDD. I am working on a project that contains reviews. Here is my domain model:

public class Survey { public int? SurveyID { get; set; } public string Name { get; set; } public decimal MinAcceptanceScore { get; set; } public int UserFailsCount { get; set; } public IEnumerable<SurveyQuestion> Questions { get; set; } public IEnumerable<Prize> Prizes { get; set; } public IEnumerable<SurveyAttempt> UserAttempts { get; set; } } 

I need different parts of the polls for different views, so I created different ViewModels:

  public class ShortSurveyViewModel { public int? SurveyID { get; set; } public string Name { get; set; } public int UserFailsCount { get; set; } public IEnumerable<SurveyAttempt> UserAttempts { get; set; } } public class ShortSurveyWithPrizesViewModel { public int? SurveyID { get; set; } public string Name { get; set; } public int UserFailsCount { get; set; } public IEnumerable<SurveyAttempt> UserAttempts { get; set; } public IEnumerable<Prize> Prizes { get; set; } } public class SurveyEditViewModel { public int? SurveyID { get; set; } public string Name { get; set; } public decimal MinAcceptanceScore { get; set; } public int UserFailsCount { get; set; } public IEnumerable<SurveyQuestion> Questions { get; set; } public IEnumerable<Prize> Prizes { get; set; } } 

What is the best way to build my architecture if I want to get the information needed for a matching type model in my survey repository?

Various solutions that I see:

  • The repository can return IQueryable to SurveyService, and the service can return a compliance model, but I do not dare that this is correct, because I think that view models should be created in the user interface, and not in the service.

  • Create three suitable classes in my domain. But now the domain will depend on the view and with each new view a new domain class must be created.

  • Get the full domain object and display only the properties necessary for a particular view. This is not good, because in my example, questions are needed in only one view, and it can be a heavy collection.

+6
source share
2 answers

Domain Managed Project:

  • You must have a repository that returns the aggregated root - in your case, Survey and all relationships that cannot exist without a parent Survey
  • This repository will always load the entire Survey class, and depending on your requirements, only some relationships (a truly dogmatic DDD will always load the entire collection, but this is not a good approach for a website without a name).
  • Your application layer (controller) will request a repository for Survey and selected relationships and display view models.

Bow architecture:

  • You will create several repositories by exposing IQueryable<Survey> - even worse, you will use a common repository with CRUD interface
  • You will create some service calling repository and build the Linq-to-entities projection into your DTOs and return them to the application level (controller).
  • Now what? You can use these DTOs directly or use a different set of objects used as view models, with some attributes related to the user interface, etc. Obviously, something is wrong ...

Simple architecture:

  • You will use the entered IDbSet<Survey> directly in your controller as a repository
  • You will make Linq-to-entities predictions directly in your controller to populate view models.

There is no better way. It is always about your goal and your expectations. For small applications, you can live with a simple architecture without any problems.

A domain-driven project is more complex. The main concept of DDD are domain objects, value objects and their composition. A domain object encapsulates data and logic performed on that data. DDD does not work with partial data or DTO - when your domain objects do not have any logic, you are doing it wrong (this is called the anemic model). A service in DDD is not an intermediary between the application layer and the repository. It is used to process business logic that is not associated with a single domain object (therefore, cannot be encapsulated in a domain entity). A repository is the infrastructure code needed to materialize your aggregates from storage and store them in storage. Application logic (controller) can interact with domain objects, services, and infrastructure code.

I don't like onion architecture.

+8
source

Given the fact that your main concern is the amount of data obtained from the Data Model and the amount of data needed in the View Model, I would say that the right approach for you is to create Views in the database and their corresponding data models.

This will allow you to trim the amount of data received from the database on any trip.

Although data models almost mimic view models, this is not a problem; they serve two different purposes. The view model is intended for presentation for binding - the data model knows how to get and save data. The construction of these representations will allow you to obtain data in an optimal way - and nevertheless, build custom logic for saving in the same models to make them writable, if necessary, so there is a need for the data model to move data from one level another.

0
source

All Articles