“Best Practices for Designing DTOs (Data Transfer Objects) in C#”?
3 min readJul 12, 2024
A lot of people ask what is the better way to generate DTO (data transfer object ), it depends on your source or coming entity that wants to map there are a lot of criteria based on these criteria you decide what the way you will create your DTO, I will show you the 6 ways that can generate you DTO based on the src entity want to map or you want to generate DTO to transfer between your layers.
Record
- store in heap
- must provide value for id
- compare by property value not reference
- immutable can It modified after initialize
- better for immutable. and src entity may be null like FirstOrDefault, and the property required to initialize.
Record Struct
- store in a stack better for GC (garbage collector).
- struct has a default parameterless constructor so you can initialize without passing the value.
- have two styles of initialize property better if you have many properties when trying to initialize.
- compare by property value not reference.
- can’t accept a null value.
- better for memory, and the src entity must have a value like First( ), and property not required to initialize.
- not immutable value can modified after initialization.
Readonly Record Struct
- The same as the record struct but can’t modified after initialization.
Class with init
- store in a heap.
- compare by reference.
- the immutable value can’t be modified after initialization.
- prefer when the property is optional to initialize you can add value to Id or not.
Class with init and required
- The same as a class with init but the property must take value when trying to initialize.
Class with primary constructor
- store in a heap.
- compare by reference.
- the immutable value can’t be modified after initialization.
If any style of DTO you using you can mention it in the comment.