Before you begin: Join our book community on Discord

Give your feedback straight to the author himself and chat to other early readers on our Discord server (find the “architecting-aspnet-core-apps-3e” channel under EARLY ACCESS SUBSCRIPTION).

https://packt.link/EarlyAccess

In this chapter, we explore object mapping. As we saw in the previous chapter, working with layers often leads to copying models from one layer to another. Object mappers solve that problem. We first look at manually implementing an object mapper. Then, we improve our design by regrouping the mappers under a mapper service, exploring the Aggregate Services, and Mapping façade patterns along the way. Finally, we replace that manual work with two open-source tools that helps us generate business value instead of writing mapping code.In this chapter, we cover the following topics:

  • Overview of object mapping and object mappers
  • Implementing a simple object mapper
  • Exploring the too-many-dependencies code smell
  • Exploring the Aggregate Services pattern
  • Implementing a Mapping Façade by leveraging the Façade pattern
  • Using the Service Locator pattern to create a flexible Mapping Service in front of our mappers
  • Using AutoMapper to map an object to another, replacing our homebrewed code
  • Using Mapperly instead of AutoMapper

Object mapper

What is object mapping? In a nutshell, it is the action of copying the value of an object’s properties into the properties of another object. But sometimes, properties’ names do not match; an object hierarchy may need to be flattened and transformed. As we saw in the previous chapter, each layer can own its own model, which can be a good thing, but that comes at the price of copying objects from one layer to another. We can also share models between layers, but even then, we usually need to map one object into another. Even if it’s just to map your models to Data Transfer Objects (DTOs), it is almost inevitable.

Remember that DTOs define our API’s contract. Independent contract classes help maintain the system, making us choose when to modify them. If you skip that part, each time you change your model, it automatically updates your endpoint’s contract, possibly breaking some clients. Moreover, if you input your model directly, a malicious user could try to bind the values of properties that they should not, leading to potential security issues (known as over-posting or over-posting attacks). Having good data exchange contracts is one of the keys to designing robust systems.

In the previous projects, the mapping logic was hardcoded, sometimes duplicated and adding additional responsibilities to the class doing the mapping. In this chapter, we extract the mapping logic into object mappers to fix that issue.

Goal

The object mapper’s goal is to copy the value of an object’s properties into the properties of another object. It encapsulates the mapping logic away from where the mapping takes place. The mapper is also responsible for transforming the values from the original format to the destination format when both objects do not follow the same structure.