Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automapper vs Dapper for mapping

This question is to verify if the current implementation is the right way to go about in terms of best practices and performance. So far in all my previous companies I have been using Auto Mapper to map relational objects to domain model entities and domain model entities to Dtos. The ORM tools have been Entity framework. In my current company they are using Dapper as ORM tool and do not use AutoMapper as they say Dapper does the mapping for you internally. So the way they have structured the project is create a separate class library project that contains Dtos and reference the Dtos in Dataccess and Business layer. The query returned by Dapper is internally mapped to the Dtos. These Dtos are returned to the Business layer and so on.

For example

In the code below the Participant function is Dto.

Repository file in DataAccess layer

 public List<ParticipantFunction> GetParticipantFunctions(int workflowId)
        {
            // Update the Action for Participant
            string selectSql = @"SELECT [WFPatFunc_ID] AS WFPatFuncID
                        ,[WFFunction]
                        ,[SubIndustryID]
                        ,[DepartmentID]
                    FROM [dbo].[WF_ParticipantsFunctions]
                    WHERE [DepartmentID] = (SELECT TOP 1 [DepartmentID] FROM [dbo].[WF] WHERE [WF_ID] = @workflowId)";

            return _unitOfWork.GetConnection().Query<ParticipantFunction>(selectSql, new
            {
                workflowId = workflowId
            }).ToList();
        }

The reason what I have been told by the developers is that AutoMapper would be just an overhead and reduce speed and since Dapper does mapping internally, there is no need for it.

I would like to know if the practice they are following is fine and have no issues.

like image 553
Tom Avatar asked Jun 27 '17 08:06

Tom


2 Answers

There is no right or wrong here. If the current system works and solves all their requirements, then great: use that! If you have an actual need for something where auto-mapper would be useful, then great: use that!

But: if you don't have a need for the thing that auto-mapper does (and it appears that they do not), then... don't use that?

Perhaps one key point / question is: what is your ability to refactor the code if your requirements change later. For many people, the answer there is "sure, we can change stuff" - so in that case I would say: defer on adding an additional layer until you actually have a requirement for an additional layer.

If you will absolutely not be able to change the code later, perhaps due to lots of public-facing APIs (software as a product), then it makes sense to de-couple everything now so there is no coupling / dependency in the public API. But: most people don't have that. Besides which, dapper makes no demands on your type model whatseover other than: it must look kinda like the tables. If it does that, then again: why add an additional layer if you don't need it?

like image 84
Marc Gravell Avatar answered Oct 16 '22 14:10

Marc Gravell


This is more of an architecture problem and there is no good or bad.

Pros of DTOs:

Layering - You are not directly using data object so you can use Attributes for mapping and stuff not needed in your UI. That way you can have the DTOs in a library that has no dependencies to your data access stuff.(Note you could do this with fluent mapping but this way you can use what you like)

Modification - If you domain model changes your public interface will stay the same. Lets say you add a property to the model all the stuff you already build wont be getting the new field in you JSON for no reason.

Security - This is why Microsoft started pushing DTOs if I remember correctly I think CodePlex(Not 100% sure it was them) was using EF entitles directly to add stuff to the database. Someone figure this out and just expanded the JSON with stuff that he was not allowed to access, for example if you have a post that has a reference to a user you could change the role of the user by adding a new post because of change tracking. There are ways to protect you self from this but security should always be an opt-out not opt-in.

I like to use DTOs when I need to expose BI level to a public interface. For example if I have an API that has System operations like api/Users/AllUsers or api/Users/GetFilteredUsers.

No DTOs

Performance - Generally not using DTOs will run faster. No extra step of mapping. Projections help with this but you can really optimize when you know what you need to do.

Speed of development and smaller code base - Sometime a large architecture is an overkill and you just want to get things done. And you are not just doing copy paste of your properties for most of you time.

More flexibility - This is opposite to the security sometimes you want to use the same api to do more then one thing. For example if you want to have the UI decide what it wants to see from a big object. Like select and expand. (Note this can be done with DTOs but if you ever tried to do expand with DTOs you know how tricky it can get)

I use it when I need to expose the data access level to the client, if you need to use Breeze or JayData and/or Odata. With api like api/Users and api/Users?filter=(a=>a.Value > 5)

like image 12
Filip Cordas Avatar answered Oct 16 '22 13:10

Filip Cordas