In actual software development projects, our "business logic" often requires us to perform various transformations on the same data. For example, a Web application collects user input into Dto through the front-end, converts Dto into a domain model, and persists it to the database. On the other hand, when a user requests data, we need to do the opposite: Convert the domain model queried from the database into Dto and then present it to the user. Sometimes we are faced with more data usage requirements, such as multiple data clients. Each client has its own requirements for different data structures, this also requires more data conversion.
Frequent data conversions are trivial and messy, and we have:
(1) In the two types, the names are almost different and the structure is similar. However, data can only be transferred between types in the way of manual and attribute assignment one by one ".
(2) Each time you encounter a new data conversion scenario, you can manually implement a set of conversion logic, which leads to repeated data conversion operations and scattered throughout the application.
If there is such a "Transformers" tool that turns "oranges" into the "apple" we want, what we need to do is to define the conversion rules-to do our real business logic, or even in a simple scenario, even rules do not need to be defined (Convention Over Configuration). This is a wonderful thing. In fact, in. NET, we don't need to reinvent the wheel because we have -- AutoMapper, a powerful Object-Object Mapping tool.
Well, I admit that I am a little excited. In fact, my projects are experiencing the above "confusions", and AutoMapper does give me a clear impression. So I spent a little time off over the weekend trying a little bit of AutoMapper, and realized the ing of Dto to domain models through small application scenarios, and indeed felt its "Strong aura ". I will share my experiences in this article, hoping to help you in the same confusion. The complete project code will be released to your git repository later. You are welcome to use it for reference.
[1] application scenarios
Let's take a look at our "virtual" domain model. This time I defined a BookStore ):
C # code
Public class BookStore
{
Public string Name {get; set ;}
Public List <Book> Books {get; set ;}
Public Address {get; set ;}
}
Public class BookStore
{
Public string Name {get; set ;}
Public List <Book> Books {get; set ;}
Public Address {get; set ;}
}
The bookstore has its own Address (Address ):
C # code
Public class Address
{
Public string Country {get; set ;}
Public string City {get; set ;}
Public string Street {get; set ;}
Public string PostCode {get; set ;}
}
Public class Address
{
Public string Country {get; set ;}
Public string City {get; set ;}
Public string Street {get; set ;}
Public string PostCode {get; set ;}
}
At the same time, there are n books in the bookstore ):
C # code
Public class Book
{
Public string Title {get; set ;}
Public string Description {get; set ;}
Public string Language {get; set ;}
Public decimal Price {get; set ;}
Public List <Author> Authors {get; set ;}
Public DateTime? PublishDate {get; set ;}
Public Publisher {get; set ;}
Public int? Paperback {get; set ;}
}
Public class Book
{
Public string Title {get; set ;}
Public string Description {get; set ;}
Public string Language {get; set ;}
Public decimal Price {get; set ;}
Public List <Author> Authors {get; set ;}
Public DateTime? PublishDate {get; set ;}
Public Publisher {get; set ;}
Public int? Paperback {get; set ;}
}
Each book has Publisher Information (Publisher ):
C # code
Public class Publisher
{
Public string Name {get; set ;}
}
Public class Publisher
{
Public string Name {get; set ;}
}
Each book can have up to two authors (Author ):
C # code
Public class Author
{
Public string Name {get; set ;}
Public string Description {get; set ;}
Public ContactInfo {get; set ;}
}
Public class Author
{
Public string Name {get; set ;}
Public string Description {get; set ;}
Public ContactInfo {get; set ;}
}
Each author has his own contact information (ContactInfo ):
C # code
Public class ContactInfo
{
Public string Email {get; set ;}
Public string Blog {get; set ;}
Public string Twitter {get; set ;}
}
Public class ContactInfo
{
Public string Email {get; set ;}
Public string Blog {get; set ;}
Public string Twitter {get; set ;}
}
This is almost the case. A domain model with a hierarchical structure.
Let's take a look at our Dto structure.
In Dto, We have BookStoreDto corresponding to BookStore:
C # code
Public class BookStoreDto
{
Public string Name {get; set ;}
Public List <BookDto> Books {get; set ;}
Public AddressDto Address {get; set ;}
}
Public class BookStoreDto
{
Public string Name {get; set ;}
Public List <BookDto> Books {get; set ;}
Public AddressDto Address {get; set ;}
}
It contains the AddressDto corresponding to the Address:
C # code
Public class AddressDto
{
Public string Country {get; set ;}
Public string City {get; set ;}
Public string Street {get; set ;}
Public string PostCode {get; set ;}
}
Public class AddressDto
{
Public string Country {get; set ;}
Public string City {get; set ;}
Public string Street {get; set ;}
Public string PostCode {get; set ;}
}
And BookDto corresponding to Book:
C # code
Public class BookDto
{
Public string Title {get; set ;}
Public string Description {get; set ;}
Public string Language {get; set ;}
Public decimal Price {get; set ;}
Public DateTime? PublishDate {get; set ;}
Public string Publisher {get; set ;}
Public int? Paperback {get; set ;}
Public string FirstAuthorName {get; set ;}
Public string FirstAuthorDescription {get; set ;}
Public string FirstAuthorEmail {get; set ;}
Public string FirstAuthorBlog {get; set ;}
Public string FirstAuthorTwitter {get; set ;}
Public string SecondAuthorName {get; set ;}
Public string SecondAuthorDescription {get; set ;}
Public string SecondAuthorEmail {get; set ;}
Public string SecondAuthorBlog {get; set ;}
Public string SecondAuthorTwitter {get; set ;}
}
Public class BookDto
{
Public string Title {get; set ;}
Public string Description {get; set ;}
Public string Language {get; set ;}
Public decimal Price {get; set ;}
Public DateTime? PublishDate {get; set ;}
Public string Publisher {get; set ;}
Public int? Paperback {get; set ;}
Public string FirstAuthorName {get; set ;}
Public string FirstAuthorDescription {get; set ;}
Public string FirstAuthorEmail {get; set ;}
Public string FirstAuthorBlog {get; set ;}
Public string FirstAuthorTwitter {get; set ;}
Public string SecondAuthorName {get; set ;}
Public string SecondAuthorDescription {get; set ;}
Public string SecondAuthorEmail {get; set ;}
Public string SecondAuthorBlog {get; set ;}
Public string SecondAuthorTwitter {get; set ;}
}
Note that our BookDto has flattened the hierarchy of the entire Book. A BookDto contains data in all modes such as Book and all its Author and Publisher.
Let's take a look at the ing rules between Dto and Model.
(1) BookStoreDto-> BookStore
Fields in BookStoreDto
Name
Books
Address
(2) AddressDto-> Address
The Address field in AddressDto
Country
City
Street
PostCode
(3) BookDto-> Book.
Some basic fields in BookDto can be directly mapped to fields in Book.
Fields in the BookDto field Book
Title
Description
Language
Price
PublishDate
Paperback
Each book has at most two authors, which are represented by fields with the "First" prefix and "Second" prefix respectively in BookDto. Therefore, all FirstXXX fields are mapped to the 1st Author objects in the Authors of the Book, and all SecondXXX fields are mapped to the 2nd Author objects in the Authors.
Fields in the 1st Author objects in the Authors field in the BookDto field Book
FirstAuthorName Name
FirstAuthorDescription Description
FirstAuthorEmail ContactInfo. Email
FirstAuthorBlog ContactInfo. Blog
FirstAuthorTwitter ContactInfo. Twitter
Note that ContactInfo. Email in the above table indicates the Email field corresponding to the ContactInfo of the Author object, and so on. Similarly, we have:
Fields in the 2nd Author objects in the Authors field in the BookDto field Book
SecondAuthorName Name
SecondAuthorDescription Description
SecondAuthorEmail ContactInfo. Email
SecondAuthorBlog ContactInfo. Blog
SecondAuthorTwitter ContactInfo. Twitter
There is also the Publisher field, which corresponds to an independent Publisher object.
Publisher field in BookDto
Publisher Name
This is almost the case. Our requirement is to convert the data between this Dto and another Model.