Note: The code for this series of articles can be downloaded here.
In the previous article we constructed a complete application scenario, including our model, the DTO, and the transformation rules between them. You can roll up your sleeves and start our AutoMapper tour.
"Two" object mappings with zero configuration implemented in Convention mode
Our addressdto is exactly the same as the address structure, and the field names are exactly the same. For this type of conversion, AutoMapper gives us the convention, as it says on the official web:
Reference
AutoMapper uses a convention-based matching algorithm to match up source to destination values.
All we have to do is tell AutoMapper (call the static method of the Mapper class Createmap and pass in the type to be mapped) to the two types that will be mapped:
C # code
Mapper.createmap<addressdto, address> ();
Then we can hand it over to AutoMapper to help us get everything done:
C # code
Addressdto dto = new Addressdto
{
Country = "China",
City = "Beijing",
Street = "Dongzhimen Street",
Postcode = "100001"
};
Address address = mapper.map<addressdto,address> (Dto);
Address. Country.shouldequal ("China");
Address. City.shouldequal ("Beijing");
Address. Street.shouldequal ("Dongzhimen Street");
Address. Postcode.shouldequal ("100001");
If there is a null attribute in the Addressdto, AutoMapper will also set the corresponding property in address to NULL when mapping:
C # code
Address address = mapper.map<addressdto,address> (new addressdto
{
Country = "China"
});
Address. City.shouldbenull ();
Address. Street.shouldbenull ();
Address. Postcode.shouldbenull ();
Even passing in an empty addressdto,automapper will help us get an empty address object.
C # code
Address address = mapper.map<addressdto,address> (null);
Address. Shouldbenull ();
Do not think of this convention mapping as a "toy", which has considerable power when mapping complex types with the same field names.
For example, consider our mapping of bookstoredto to bookstore, where the field names are exactly the same, except for the type of the fields that are inconsistent. If we define the mapping rules for the bookdto to book, plus the Addressdto to address mapping of the Convention method described above, you can implement bookstoredto to bookstore mappings with "0 Configuration":
C # code
Imappingexpression<bookdto, book> expression = mapper.createmap<bookdto,book> ();
Define mapping rules from Bookdto
Mapper.createmap<addressdto, address> ();
Mapper.createmap<bookstoredto, bookstore> ();
Then we can convert the Bookstoredto directly:
C # code
Bookstoredto dto = new Bookstoredto
{
Name = "My Store",
Address = new Addressdto
{
City = "Beijing"
},
Books = new List<bookdto>
{
New Bookdto {Title = "RESTful Web Service"},
New Bookdto {Title = "Ruby for Rails"},
}
};
Bookstore Bookstore = mapper.map<bookstoredto,bookstore> (DTO);
BookStore.Name.ShouldEqual ("My Store");
BookStore.Address.City.ShouldEqual ("Beijing");
BookStore.Books.Count.ShouldEqual (2);
BookStore.Books.First (). Title.shouldequal ("RESTful Web Service");
BookStore.Books.Last (). Title.shouldequal ("Ruby for Rails");
Simple mapping rules between "three" definition types
Before we looked at the mapping of Convention, objectively speaking, there are many types of mapping can not be done by a simple convention way, this time we need to use the configuration. Fortunately, our configuration is written in code in a "strongly typed" way, which is much better than writing tedious and error-prone XML.
Let's take a look at the mapping of Bookdto to Publisher.
Review the rules defined in the previous article: Bookdto.publisher-Publisher.name.
In Automapperzhong, we can map this:
C # code
var map = mapper.createmap<bookdto,publisher> ();
Map. Formember (d = d.name, opt = = opt. Mapfrom (s = s.publisher));
AutoMapper uses Formember to specify a mapping rule for each field:
Reference
The each custom member configuration uses a action delegate to configure each member.
Fortunately there is a powerful lambda expression, and the definition of the rule is straightforward.
In addition, we can use the Constructusing method to directly define the mapping rules for all fields at once. For example, to define the mapping of the bookdto to the first author (Author) ContactInfo, using the Constructusing method, we can:
C # code
var map = mapper.createmap<bookdto,contactinfo> ();
Map. Constructusing (s = new ContactInfo
{
Blog = S.firstauthorblog,
Email = S.firstauthoremail,
Twitter = S.firstauthortwitter
});
Then, you can use it in the way we know it:
C # code
Bookdto dto = new Bookdto
{
Firstauthoremail = "Matt.rogen@abc.com",
Firstauthorblog = "Matt.amazon.com",
};
ContactInfo ContactInfo = mapper.map<bookdto, contactinfo> (DTO);
If the 2 types that need to be mapped have the same partial field names, are some field names different? Fortunately AutoMapper gives us the Convention or configuration method is not "XOR", we can use a combination of two ways, the name of a different field configuration mapping rules, and for the same name of the field is ignored configuration.
For example, for the previously mentioned addressdto to address mapping, if the Addressdto field country is not called country countryname, then when writing addressdto to address mapping rules, you only need:
C # code
var map = mapper.createmap<addressdto, address> ();
Map. Formember (d = d.country, opt = = opt. Mapfrom (s = s.countryname));
There is no need to define any rules for City, street, and postcode, and AutoMapper can still help us do the right mapping.