locked
AutoMapper convention wise RRS feed

  • Question

  • User-375835195 posted

    Hello guys,

    I have a ASP.NET Core 2.2 Web API with Angular front-end. I've been told that AutoMapper isn't meant for ViewModel -> Persistence/Domain Model conversions. In addition to that, there was a post from the creactor of AutoMapper: https://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/ and one more: https://rogerjohansson.blog/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/.

    I'm posting this because I'm not quite sure if that's what they meant.

    Question 1) According to my understanding, those posts mean that AutoMapper isn't meant two-way mapping. If it was not intended for two-way mapping, then why does ReverseMap() exist? Or did they mean that it was not intended for Dto model -> Domain model if any of the properties that have to be mapped are involved with Entity Framework as such as var cryptoPair = await _context.CryptoPairs.FirstOrDefaultAsync(e => e.Symbol == botDto.Symbol);?

    I have two of my services linked below. I think what I did in `GetAllAsync()` and `GetByIdAsync()` is alright in both services.

    What about CreateAsync() and UpdateAsync()? The first service has two properties (cryptoPair and timeInterval in CreateAsync() and UpdateAsync()) that should be queried from DbContext which basically means that EF is involved in that situation and in fact, I didn't use AutoMapper in my service. The second service of mine does Dto -> Domain model (what they basically said that AutoMapper wasn't intended for) in CreateAsync() and UpdateAsync() but it doesn't involve EF. Can you please tell me if what I did in my code is alright with an explanation.

    Quote from the second article: AutoMapper knows nothing about EF and ID’s so it will simply recreate every object in the .Details collection. This might lead to consequences with bigger Dto models.

    Service 1: https://pastebin.com/W8vdDPxK

    Service 2: https://pastebin.com/7hjAnUsA

    Question 2) In the first service, if I wanted to return a different Dto model only in GetAllAsync() (the model below), would it be acceptable if that service had used multiple Dto models (in this case two Dto models)?

    public class BotDisplayDto
    {
    	public int Id { get; set; }
    	public string Name { get; set; }
    	public bool Status { get; set; }
    	public CryptoPair CryptoPair { get; set; }
    	public TimeInterval TimeInterval { get; set; }
    }

    Wednesday, August 21, 2019 3:55 PM

Answers

  • User-821857111 posted

    Jimmy Bogard's post (from 10 years ago) says that he decided not to implement 2-way mapping at the outset, but then he asks why people would want it. Since then, he has implemented two-way mapping. He didn't say that two-way mapping is wrong. He just didn't envisage a use for it, probably because he was using a Domain Driven Design approach to app development:

    There is no two-way mapping because we never need two-way mapping.  There was a point very early on where we were at a critical junction, and could decide to do two-way mapping.  But we didn’tWhy?  Because then our mapping layer would influence our domain model.

    A lot of applications are simple CRUD apps. In those, the "domain model" typically doesn't have very much behaviour, and is therefore seen as "anaemic". ViewModels often mirror the domain model, with a few properties missing, perhaps, and having a simple mapper to transfer values from a viewmodel/dto to a domain model is not such a big deal. So Jimmy included ReverseMap.

    There is no such thing as "best practice" when it comes to a utility like AutoMapper. It's a tool. Nothing more. It has a defined feature set. If those features help you, use them. As with all tools and framework, you should understand what it is doing behind the scenes, which is the essence of the other article you referenced.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 22, 2019 12:37 PM

All replies

  • User1120430333 posted
    I used Automapper once several years ago. I always like to do the mapping of properties manually.
    Wednesday, August 21, 2019 9:00 PM
  • User-375835195 posted

    I think I will just keep Domain/Persistence -> Dto/VIewModel and not the opposite.

    Wednesday, August 21, 2019 9:59 PM
  • User-474980206 posted

    you are using an angular front-end which uses a binders to injected services. these services should be making ajax calls to the webapi. The webapi should have request / response models for each endpoint that may map a request / response to the DTO models.

    if you are using view models, these are javascript objects used between the injected services and the components for component binding. the webapi / server should not know about these view models.

    note: I've never found automapper to be less work then using linq queries (which support map/reduce).

    Wednesday, August 21, 2019 10:39 PM
  • User1120430333 posted
    Dto to view model using Automapper in the MVC project was how I saw it done. Dto and persistence model was done manually
    Thursday, August 22, 2019 12:11 AM
  • User-375835195 posted

    bruce (sqlwork.com)

    you are using an angular front-end which uses a binders to injected services. these services should be making ajax calls to the webapi. The webapi should have request / response models for each endpoint that may map a request / response to the DTO models.

    if you are using view models, these are javascript objects used between the injected services and the components for component binding. the webapi / server should not know about these view models.

    note: I've never found automapper to be less work then using linq queries (which support map/reduce).

    I don't quite understand what you wanted to say.

    Either way, I found two projects on GitHub:

    1) https://github.com/Elfocrash/Youtube.AspNetCoreTutorial/blob/cbf86c3710e35234ffc5b03605380d6150b19d36/Tweetbook/Services/PostService.cs

    He used AutoMapper in the controller and mapped only Domain/Persistence -> Dto. The opposite direction, he did it the normal way as we all know. Basically, that what Jimmy's post mentioned. I actually like how he structured his code because that way he doesn't have to create custom exceptions in the services like I did. He moved that logic in the controller.

    2) https://github.com/emonney/QuickApp/blob/master/QuickApp/Controllers/AccountController.cs

    This repo has Angular bound in the project and it's kinda similar.

    I modified my code based on the first repo, here it is:

    Controller: https://pastebin.com/qL8QA0uq

    Service: https://pastebin.com/fWfpVJc7

    Let me know if you have any suggestions.

    Thursday, August 22, 2019 6:23 AM
  • User711641945 posted

    Hi Hulkstance,

    You could use AutoMapper to map between the entity and ViewModel. Did you meet the limited when you using AutoMapper?Or you have made mistakes by getting startted with these links you posted?

    Best Regards,

    Rena

    Thursday, August 22, 2019 10:00 AM
  • User-375835195 posted
    Hello Rena,

    it definitely works even if it's done the wrong way. I just wanted to make sure that it's using the best practices because of its creator's post. The question was more likely about Dto -> Domain, the opposite way is fine. Basically, about BotCreateUpdateDto -> Bot.
    Thursday, August 22, 2019 10:51 AM
  • User-821857111 posted

    Jimmy Bogard's post (from 10 years ago) says that he decided not to implement 2-way mapping at the outset, but then he asks why people would want it. Since then, he has implemented two-way mapping. He didn't say that two-way mapping is wrong. He just didn't envisage a use for it, probably because he was using a Domain Driven Design approach to app development:

    There is no two-way mapping because we never need two-way mapping.  There was a point very early on where we were at a critical junction, and could decide to do two-way mapping.  But we didn’tWhy?  Because then our mapping layer would influence our domain model.

    A lot of applications are simple CRUD apps. In those, the "domain model" typically doesn't have very much behaviour, and is therefore seen as "anaemic". ViewModels often mirror the domain model, with a few properties missing, perhaps, and having a simple mapper to transfer values from a viewmodel/dto to a domain model is not such a big deal. So Jimmy included ReverseMap.

    There is no such thing as "best practice" when it comes to a utility like AutoMapper. It's a tool. Nothing more. It has a defined feature set. If those features help you, use them. As with all tools and framework, you should understand what it is doing behind the scenes, which is the essence of the other article you referenced.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 22, 2019 12:37 PM
  • User-375835195 posted

    Jimmy Bogard's post (from 10 years ago) says that he decided not to implement 2-way mapping at the outset, but then he asks why people would want it. Since then, he has implemented two-way mapping. He didn't say that two-way mapping is wrong. He just didn't envisage a use for it, probably because he was using a Domain Driven Design approach to app development:

    There is no two-way mapping because we never need two-way mapping.  There was a point very early on where we were at a critical junction, and could decide to do two-way mapping.  But we didn’tWhy?  Because then our mapping layer would influence our domain model.

    A lot of applications are simple CRUD apps. In those, the "domain model" typically doesn't have very much behaviour, and is therefore seen as "anaemic". ViewModels often mirror the domain model, with a few properties missing, perhaps, and having a simple mapper to transfer values from a viewmodel/dto to a domain model is not such a big deal. So Jimmy included ReverseMap.

    There is no such thing as "best practice" when it comes to a utility like AutoMapper. It's a tool. Nothing more. It has a defined feature set. If those features help you, use them. As with all tools and framework, you should understand what it is doing behind the scenes, which is the essence of the other article you referenced.

    Thank you! That's what I wanted to hear.

    Thursday, August 22, 2019 1:27 PM