5

I'm using Automapper in Asp.net mvc application. I have a question regard to the usage of automapper

from lots of sample code, I saw people use mapper Mapper.Map<Target>(source) directly in action, I'm not sure if this is good prctice, in my point of view, I would like to wrap the Mapper code in the proxy object instead of let it talk with controller directly

      public BankflowData CreateBankflowAdjustments(BankflowData addedBankFlow)
      {
         var bankflow = Mapper.Map<Bankflow>(addedBankFlow);
         var newBankflow = Underlying.CreateBankFlowAdjustments(bankflow);
         return Mapper.Map<BankflowData>(newBankflow);
      }

in this example, controller know nothing about Class Bankflow, all it know is the dto BankflowData.

I would like to know if this is a good practice for an application using AutoMapper?

Liath
  • 9,913
  • 9
  • 51
  • 81
Sean
  • 2,990
  • 1
  • 21
  • 31

2 Answers2

6

For a previous question, I answered ASP.NET MVC with service layer and repository layer, where should the interfaces be defined?

In my answer, I explained:

[...] I have a typical structure like this:

  • MyProject.Core
  • MyProject.Domain
  • MyProject.DependencyInjection
  • MyProject.Infrastructure
  • MyProject.Web
  • MyProject.Tests

The Infrastructure layer contains information about logging, emailing and data access. It will contain my ORM of choice. It's not business-logic stuff and it's not UI stuff. It's the railroad of my solution to get things done. It's on the outer layer but it only references the Core.

In my case the infrastructure layer also houses Automapper. The core defines a simple interface (let's say IAutoMapper) and a simple object that exists in the infrastructure implements it and the object can be passed to the UI layer through dependency injection.

However Jimmy Bogard (the creator of Automapper) said in AutoMapper 3.0, Portable Class Libraries and PlatformNotSupportedException

[...] if you whine about UI projects shouldn’t reference this library directly because of some silly faux architect-y reason (even referencing a certain smelly round vegetable), I will drive to your house and slap you silly. Get off your high horse and start being productive.

From what I understand he means that it's ok to reference Automapper from the UI layer. When he says "a certain smelly round vegetable" he is, of course, referring to Onion Architecture which Jimmy is not a big fan of.

Community
  • 1
  • 1
Rowan Freeman
  • 15,724
  • 11
  • 69
  • 100
  • thanks for your answer, yes I agree with you to put non business-logic code in the infrasturcture and wrapper Automapper with a simple Interface, but my question is Sould I expose Domain directly to Controller? or wrapper by a proxy object, and only expose DTO to controller? eg: I have a service object which return Domain object `Cashflow` which is a quite big object, mean while I have a DTO object CashflowDTO which is a lightweight object, the service object only take domain object as parameter or result – Sean Feb 07 '14 at 06:15
  • so I have two chice, 1. map dto to domain object in controller layer(which I don't like) 2. wrapper server with a proxy object and map dto there, I prefer the second choice, what's your idea? – Sean Feb 07 '14 at 06:17
  • I always make use of AutoMapper from the UI since the UI got the ViewModel and from there I send the mapping value to the Service layer which continue with business logic and so one. I also have a InnerCore => ViewModel => Services where I do some operations that implies ViewModel only before sending the result to the Service layer. Things go pretty well. – David Létourneau May 29 '18 at 15:22
3

if you have service layer in your application, it's better to place the automapper in service layer. in any case try to use extension method for mapping your object by automapper like this:

public static class Mapping
{
public static BankflowData CreateBankflowAdjustments(this BankflowData addedBankFlow)
      {
         var bankflow = Mapper.Map<Bankflow>(addedBankFlow);
         var newBankflow = Underlying.CreateBankFlowAdjustments(bankflow);
         return Mapper.Map<BankflowData>(newBankflow);
      }
}

it will make your code more readable and will separate your concerns. take this for more info

Ehsan
  • 816
  • 9
  • 27
  • the example looks good, so your idea is to use extend method to encapslate the `Mapper.Map` and call DTO.ToDomain(), do you? you also agree that mapper code should be placed in service layer instead of controller layer, right? – Sean Feb 07 '14 at 11:55
  • yes, but if you have service layer it's best places to put them over there, because the best place to map the DTO or ViewModel to Domain entities is service layer. although you can put them in your controller if your application is not big enough but try to use extension method to make your code clean. – Ehsan Feb 07 '14 at 12:08