Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing DTO to my ViewModels constructor to map properties

In my solution I have two projects.

Project 1 (Core) Mapping SQL to DTO using Dapper

Project 2 (WebUI - ASP.NET MVC 4) Here I use a ViewModel per View.

Examples of a Controller

  [HttpGet]
    public ActionResult Edit(int id)
    {
        // Get my ProductDto in Core
        var product = Using<ProductService>().Single(id);
        var vm = new ProductFormModel(product);

        return View(vm);
    }

Examples of a ViewModel

public class ProductFormModel : BaseViewModel, ICreateProductCommand
    {
        public int ProductId { get; set; }
        public int ProductGroupId { get; set; }
        public string ArtNo { get; set; }
        public bool IsDefault { get; set; }
        public string Description { get; set; }
        public string Specification { get; set; }
        public string Unit { get; set; }
        public string Account { get; set; }
        public decimal NetPrice { get; set; }

        public ProductFormModel(int productGroupId)
        {
            this.ProductGroupId = productGroupId;
        }

        public ProductFormModel(ProductDto dto)
        {
            this.ProductId = dto.ProductId;
            this.ProductGroupId = dto.ProductGroupId;
            this.ArtNo = dto.ArtNo;
            this.IsDefault = dto.IsDefault;
            this.Description = dto.Description;
            this.Specification = dto.Specification;
            this.Unit = dto.Unit;
            this.Account = dto.Account;
            this.NetPrice = dto.NetPrice;
        }

        public ProductFormModel()
        {
        }
    }

Explanation: I'll get my DTOs in my controller using a service class in the project (Core). Then i create my ViewModel and pass the DTO to the constructor in ViewModel. I can also use this view to add a new Product because my ViewModel can take a empty constructor.

Does anyone have experience of this. I wonder if I am in this way will have problems in the future as the project gets bigger?

I know this has nothing to do with Dapper. But I would still like a good way to explain my solution.

like image 673
Nils Anders Avatar asked Jan 14 '13 11:01

Nils Anders


People also ask

Does a DTO have a constructor?

Data Transfer Objects are public (static) classes with no methods, other than the compiler supplied default constructor, having only public fields limited to the easily serializable types: i.e. A DTO is equivalent to a struct in C.

Is a Viewmodel a DTO?

Data Transfer Objects (DTOs) and View Models (VMs) are not the same concept! The main difference is that while VMs can encapsulate behaviour, DTOs do not. The purpose of a DTO is the transfer of data from one part of an application to another.

What is the difference between DTO and Viewmodel in DDD?

The purpose is different: DTO's are used to transfer data. ViewModels are used to show data to an end user.


2 Answers

I think you will be fine using your current approach. More importantly, start out like this and refactor if you start to encounter problems related to your object mapping code (instead of thinking too much about it beforehand).

Another way to organize mapping logic that I use sometimes is to employ extension methods. That way, the mapping code is kept separate from the view model itself. Something like:

public static class ProductMappingExtensions
{
    public static ProductFormModel ToViewModel(this ProductDto dto)
    {
        // Mapping code goes here
    }
}

// Usage:

var viewModel = dto.ToViewModel();

Yet another approach would be to use a mapping framework like AutoMapper - this is a good fit in particular if your mapping logic is simple (lots of 1:1 mappings between properties).

But again, start simple and refactor when you need to.

like image 130
Anders Fjeldstad Avatar answered Oct 27 '22 19:10

Anders Fjeldstad


I realize that this is a little bit late answer, but maybe it will help someone in the future.

This way of doing mapping between objects breaks the 'S' of the SOLID principles, because the responsibility of the ViewModel is to prepare data in its properties to be ready to use by the view and nothing else, therefore, mapping objects should not be on it's responsibilities.

Another drawback of this way is that it also breaks the 'Loose Coupling' OO principle as you ViewModel is strongly coupled with your DTO.

I think, even when we are in the very first step of the project, there are some importants OO principles that we should never break, so using mapper classes, either auto (AutoMapper, ValueInjecter ...) or manual, is definitely better.

like image 22
A77 Avatar answered Oct 27 '22 20:10

A77