Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying Models Between Layers

When traversing layers it is very tedious to perform right->left assignments as a way to populate the models. For example:

employeeViewModel.FirstName = employeeModel.FirstName;
employeeViewModel.LastName = employeeModel.LastName;
...

So, we can build a ModelCopier which uses reflection to copy models:

var employeeViewModel = ModelCopier.Copy<EmployeeViewModel>(employeeModel);

This technique greatly simplifies the task. However, there are a few things that are quite disturbing about this:

  • We have effectively lost the ability to track usages of properties on the source and destination objects. For example, finding usages (in Resharper) of the FirstName property does not reveal the ModelCopier cases.
  • If we change the name of a property on the source or destination class, we can unintentionally cause runtime exceptions since we might not realize that we need to update both the source and destination class.

On one end of the spectrum, we can use reflection which is very easy, but at the cost of maintainability. The opposite end of the spectrum is very tedious but very maintainable.

Reflection (Easy and Dangerous) <-----> Direct Assignment (Tedious and Maintainable)

I'm curious if anyone has found a compromise that offers the ease of using reflection for copying with the maintainability of direct assignment.

One solution we have entertained was to build a plugin that will generate extension methods that handle the assignment of properties for each case. In other words, build a tool that will handle the tedious part.

EDIT:

Please understand that this question isn't about which mapping tool to use. I'm trying to understand how we can enjoy the benefits of reflection-based mapping while also enjoying the benefits of maintainability that is provided by direct assignment (or a property map contract).

like image 335
Page Avatar asked Aug 27 '10 13:08

Page


1 Answers

Seriously, use AutoMapper. It allows you to setup conversions from one type to another type. Any changes to property names will break the configuration of the automapper, which reflection will not:

Mapper.CreateMap<SiteDto, SiteModel>();
Mapper.CreateMap<SiteModel, SiteDto>();

Then to map to and from, you just do the following:

SiteDto dto = Mapper.Map<SiteModel, SiteDto>(targetModel);
SiteModel model = Mapper.Map<SiteDto, SiteModel>(targetDto);
like image 114
djdd87 Avatar answered Nov 13 '22 00:11

djdd87