Skip to content
Leonardo Porro edited this page Jan 24, 2023 · 11 revisions

A DTO (Data Transfer Object) is an object designed to carry data. Usually DTOs are plain classes with data properties and no methods or calls, other than annotations or small routines related to serialization or validation.

In the scope of this library a DTO is the input or source value for the mapping, and can be the same entity being mapped, or a regular class with a subset of the original entity properties, or an anonymous class, or a dictionary or JSON.

Mapping from the same entity

The same entity type can be used as input data for mapping.

User user = await dbContext.MapAsync<User>(new User { Id = 1, Name = "user name" });

Entities as DTOs may work for some scenarios, but it's not the best approach for all cases.

Mapping from a DTO

Usually, entities are too complex or contain sensitive data and cannot be exposed as method inputs, so DTOs are the recommended way. Also, the goal of the library is to create as many DTOs as needed without worrying about mapping them. Some APIs, especially GraphQL ones have one input DTO per operation: SaveUser(SaveUserInput input); Finally, using per operation DTO ensures that only the defined properties are mapped and no other property is accidentally overwritten.

User user = await dbContext.MapAsync<User>(new UserDTO { Id = 2, Name = "user name" });
Mapping from an anonymous type

When a couple of properties are going to be updated, but creating a DTO is too much overhead, anonymous types can be used. Anonymous types are just regular classes with autogenerated names.

User user = await dbContext.MapAsync<User>(new { Id = 3, Name = "user name" });
Mapping from a dictionary

It's not a common case, but data from 3rd party sources, like config files can be mapped whitout using intermediate objects.

User user = await dbContext.MapAsync<User>(new Dictionary<string, object> { { "Id", 4 }, { "Name", "user name" });
Mapping from Json

Json strings and files can be deserialized and mapped to entities. Useful for seeding databases.

User user = await dbContext.MapJsonAsync<User>("[ {'Id': 1, 'Name': 'user name' } }");
User user = await dbContext.MapJsonFileAsync<User>("../users.json");

Also, more types can be added using extensions.

The main goal of the library is to make easy to handle and map DTOs and set the right entity state so developers can focus on business logic.